1. RE: Syncronising Lists
Hi There,
Here is my attempt at synchronising lists. This one involves
subclassing the list windows so that mouse and keyboard events are
processed early enough to avoid any time lag in updating the other
lists.
Regards,
Phil Russell
include Win32Lib.ew
without warning
integer oldwndproc, void
-- Window Test
global constant Test = create( Window, "List Sync", 0, Default, Default,
333, 230, 0 )
global constant List1 = create( List, "List1", Test, 8, 12, 92, 172, 0 )
global constant List2 = create( List, "List2", Test, 116, 12, 92, 172,0
)
global constant List3 = create( List, "List3", Test, 222, 12, 92, 172, 0
)
for n = 1 to 10 do
addItem(List1, "item " & sprint(n) & " list1")
addItem(List2, "item " & sprint(n) & " list2")
addItem(List3, "item " & sprint(n) & " list3")
end for
function Test_WndProc( atom hWnd, atom iMsg, atom wParam, atom lParam )
integer pos
-- intercept clicks and keypresses in the list boxes
if iMsg = WM_LBUTTONDOWN or iMsg = WM_KEYDOWN then
-- allow list box to process the message
void = w32Func( xCallWindowProc, { oldwndproc, hWnd, iMsg, wParam,
lParam } )
-- get the resulting list box selection
pos = w32Func( xSendMessage, {hWnd, LB_GETCURSEL, 0, 0 } )
-- if valid then update the other list boxes
if pos >= 0 then
if hWnd != getHandle(List1) then
setIndex(List1, pos+1)
end if
if hWnd != getHandle(List2) then
setIndex(List2, pos+1)
end if
if hWnd != getHandle(List3) then
setIndex(List3, pos+1)
end if
end if
-- we have processed this message so return false
return 0
end if
-- pass all other messages to the default list box procedure
return w32Func( xCallWindowProc, { oldwndproc, hWnd, iMsg, wParam,
lParam } )
end function
-- Subclass the list boxes
oldwndproc = w32Func( xSetWindowLong, { getHandle(List1), GWL_WndProc,
call_back(routine_id("Test_WndProc")) } )
void = w32Func( xSetWindowLong, { getHandle(List2), GWL_WndProc,
call_back(routine_id("Test_WndProc")) } )
void = w32Func( xSetWindowLong, { getHandle(List3), GWL_WndProc,
call_back(routine_id("Test_WndProc")) } )
-- Display window
WinMain( Test, Normal )
2. RE: Syncronising Lists
Hi,
Oops! Included a fix for when the user drags the mouse in a list window
(and tidied up a bit).
Phil Russell
include Win32Lib.ew
without warning
integer oldwndproc, void
-- Window Test
global constant Test = create( Window, "List Sync", 0, Default, Default,
333, 230, 0 )
global constant List1 = create( List, "List1", Test, 8, 12, 92, 172, 0 )
global constant List2 = create( List, "List2", Test, 116, 12, 92, 172,0
)
global constant List3 = create( List, "List3", Test, 222, 12, 92, 172, 0
)
for n = 1 to 10 do
addItem(List1, "item " & sprint(n) & " list1")
addItem(List2, "item " & sprint(n) & " list2")
addItem(List3, "item " & sprint(n) & " list3")
end for
function Test_WndProc( atom hWnd, atom iMsg, atom wParam, atom lParam )
integer pos, ret
-- allow list box to process the message
ret = w32Func( xCallWindowProc, { oldwndproc, hWnd, iMsg, wParam, lParam
} )
-- intercept clicks and keypresses in the list boxes
if iMsg = WM_LBUTTONDOWN
or iMsg = WM_KEYDOWN
or iMsg = WM_LBUTTONUP
-- user drags the mouse in the list box
or (iMsg = WM_MOUSEMOVE and and_bits(wParam, MK_LBUTTON))
then
-- get the resulting list box selection
pos = w32Func( xSendMessage, {hWnd, LB_GETCURSEL, 0, 0 } )
-- if valid then update the other list boxes
if pos >= 0 then
if hWnd != getHandle(List1) then
setIndex(List1, pos+1)
end if
if hWnd != getHandle(List2) then
setIndex(List2, pos+1)
end if
if hWnd != getHandle(List3) then
setIndex(List3, pos+1)
end if
end if
end if
-- return value from default list box procedure
return ret
end function
-- Subclass the list boxes
oldwndproc = w32Func( xSetWindowLong, { getHandle(List1), GWL_WndProc,
call_back(routine_id("Test_WndProc")) } )
void = w32Func( xSetWindowLong, { getHandle(List2), GWL_WndProc,
call_back(routine_id("Test_WndProc")) } )
void = w32Func( xSetWindowLong, { getHandle(List3), GWL_WndProc,
call_back(routine_id("Test_WndProc")) } )
setIndex(List1, 1)
setIndex(List2, 1)
setIndex(List3, 1)
-- Display window
WinMain( Test, Normal )
3. RE: Syncronising Lists
pg_russell at lineone.net wrote:
> Hi,
>
> Oops! Included a fix for when the user drags the mouse in a list window
> (and tidied up a bit).
>
> Phil Russell
>
> include Win32Lib.ew
> without warning
>
> integer oldwndproc, void
>
> -- Window Test
> global constant Test = create( Window, "List Sync", 0, Default, Default,
> 333, 230, 0 )
> global constant List1 = create( List, "List1", Test, 8, 12, 92, 172, 0 )
> global constant List2 = create( List, "List2", Test, 116, 12, 92, 172,0
> )
> global constant List3 = create( List, "List3", Test, 222, 12, 92, 172, 0
> )
>
> for n = 1 to 10 do
> addItem(List1, "item " & sprint(n) & " list1")
> addItem(List2, "item " & sprint(n) & " list2")
> addItem(List3, "item " & sprint(n) & " list3")
> end for
>
> function Test_WndProc( atom hWnd, atom iMsg, atom wParam, atom lParam )
>
> integer pos, ret
>
> -- allow list box to process the message
> ret = w32Func( xCallWindowProc, { oldwndproc, hWnd, iMsg, wParam, lParam
>
> } )
>
> -- intercept clicks and keypresses in the list boxes
> if iMsg = WM_LBUTTONDOWN
> or iMsg = WM_KEYDOWN
> or iMsg = WM_LBUTTONUP
> -- user drags the mouse in the list box
> or (iMsg = WM_MOUSEMOVE and and_bits(wParam, MK_LBUTTON))
> then
>
> -- get the resulting list box selection
> pos = w32Func( xSendMessage, {hWnd, LB_GETCURSEL, 0, 0 } )
>
> -- if valid then update the other list boxes
> if pos >= 0 then
> if hWnd != getHandle(List1) then
> setIndex(List1, pos+1)
> end if
> if hWnd != getHandle(List2) then
> setIndex(List2, pos+1)
> end if
> if hWnd != getHandle(List3) then
> setIndex(List3, pos+1)
> end if
> end if
> end if
>
> -- return value from default list box procedure
> return ret
>
> end function
>
> -- Subclass the list boxes
> oldwndproc = w32Func( xSetWindowLong, { getHandle(List1), GWL_WndProc,
> call_back(routine_id("Test_WndProc")) } )
> void = w32Func( xSetWindowLong, { getHandle(List2), GWL_WndProc,
> call_back(routine_id("Test_WndProc")) } )
> void = w32Func( xSetWindowLong, { getHandle(List3), GWL_WndProc,
> call_back(routine_id("Test_WndProc")) } )
>
> setIndex(List1, 1)
> setIndex(List2, 1)
> setIndex(List3, 1)
>
> -- Display window
> WinMain( Test, Normal )
>
>
It turns out that the issue is not whether or not the control is
subclassed, because Win32lib already subclasses the controls, but when
control is given to the user-written event handlers relative to the
control handling the event.
Currently, user-written handler code that is triggered by a Window
message, is called *before* the control's own code gets the message.
Thus for a List control, our onChange event gets called before the List
updates its display.
What might be nice is if win32lib has a new event type "AfterEvent" that
is called after the control has finished processing the Windows message,
but before the next message is recieved. This would be similar to the
current "Event" event type, which is called before any processing of the
Windows message is done (even by Win32lib).
If there are no objections, I'll add it to the library (should take
about 15 mins to do).
P.S. I'll be back home on the weekend and will be able to issue the next
release of the library with all the great feedback, including bug fixes,
I've had. Thanks for all your support, people.
---------
Derek.
4. RE: Syncronising Lists
Derek,
Sounds good to me.
Phil
Derek Parnell wrote:
>
> What might be nice is if win32lib has a new event type "AfterEvent" that
>
> is called after the control has finished processing the Windows message,
>
> but before the next message is recieved. This would be similar to the
> current "Event" event type, which is called before any processing of the
>
> Windows message is done (even by Win32lib).
>
> If there are no objections, I'll add it to the library (should take
> about 15 mins to do).