Hello,
As the title says, I'm trying to create a simple splitter control, but for some reason I am experiencing problems of overhead and repainted. Could someone tell me why it happens and how to fix it... :redface:
Simple project in attachments...
- when start dragging, save the original x-position of the control and the current mouse position
- whenever the mouse is moved, calculate the difference of x-coordinates for it
- add that difference to the original x-position of the control to get the current control position
- UpdateWindow is not needed, because SetWindowPos does redrawing as needed
.data
pt0 POINT <>
xorg SDWORD ?
.....
ControlWndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
LOCAL pt:POINT, rect1:RECT, rect2:RECT
.IF uMsg==WM_LBUTTONDOWN
invoke SetCapture,hWnd
; save mouse position
invoke GetCursorPos,ADDR pt0
; calculate and save control position
invoke GetWindowRect,hWnd,ADDR rect1
invoke ScreenToClient,hMainWindow,ADDR rect1
mrm xorg,rect1.left
.ELSEIF uMsg==WM_LBUTTONUP
invoke ReleaseCapture
.ELSEIF uMsg==WM_MOUSEMOVE
.IF wParam & MK_LBUTTON
; get current mouse position
invoke GetCursorPos,ADDR pt
invoke GetClientRect,hMainWindow,ADDR rect1
invoke GetWindowRect,hWnd,ADDR rect2
; maximal x-coordinate of control
; = MainWindow.client_width - Control.width
mov ecx,rect1.right
mov eax,rect2.right
sub eax,rect2.left
sub ecx,eax
; delta_x (mouse)
mov edx,pt.x
sub edx,pt0.x
; new x-position = x_org + delta_x
add edx,xorg
; the control should not go out of view
.if SDWORD ptr edx < 0
xor edx,edx
.elseif SDWORD ptr edx >= ecx
mov edx,ecx
.endif
invoke SetWindowPos, hWnd, 0, edx, 0, 0, 0, SWP_NOZORDER or SWP_NOSIZE
.ENDIF
.ELSE
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.ENDIF
xor eax,eax
ret
ControlWndProc endp
one thing that can drive your CPU usage up is....
you handle WM_PAINT without calling BeginPaint and EndPaint
when you call BeginPaint, the update region is "validated" (opposite of invalidate)
so, the OS continually sends WM_PAINT messages, thinking there is still a region that requires update
another thing i found, when using SetCapture is....
calling ReleaseCapture causes a WM_CAPTURECHANGED message to be sent
most of your actual release code should be handled in WM_CAPTURECHANGED
see the DivWin2 example attached to this post...
http://masm32.com/board/index.php?topic=2977.msg31084#msg31084 (http://masm32.com/board/index.php?topic=2977.msg31084#msg31084)
qWord, thanks for the help :t
dedndave, nice example and helpful :t btw, I think I'm not handling the WM_PAINT event... :-P
Hello guys, sorry for the double post, I was adding the code to my actual application but it seems to have problems. this happens when I drag it to the right:
(http://s17.postimg.org/54huqugu7/image.png)
Any idea? :dazzled:
Simple project in attachments... :redface:
Edited:
Project updated but still not working.
i am running XP - and i see no listview - just a divider with white (i do see the text on the left)
this is probably because of the lack of a manifest and a call to InitCommonControlsEx
;8CCh = DS_CENTER or DS_MODALFRAME or DS_SETFONT or DS_FIXEDSYS or DS_3DLOOK
invoke CreateWindowEx, WS_EX_WINDOWEDGE, addr SzWindowClass1, addr SzWindowClass1, \
WS_VISIBLE or WS_POPUPWINDOW or WS_CLIPSIBLINGS or WS_DLGFRAME or WS_GROUP or 8CCh, \
CW_USEDEFAULT, CW_USEDEFAULT, 600, 280, NULL, NULL, hPrevInst, NULL
mov hMainWindow, eax
invoke CreateWindowEx, 0, addr SzWindowClass2, NULL, WS_CHILD or WS_VISIBLE, \
200, 0, SPLITTER_SIZE, 280, hMainWindow, NULL, hPrevInst, NULL
mov hSplitter, eax
normally, WS_CLIPSIBLINGS is used on child windows only
and WS_CLIPCHILDREN is used on the parent window
i believe WS_GROUP is also a style used only with child windows
.ELSEIF uMsg==WM_LBUTTONUP
invoke ReleaseCapture
you have no code to perform the actual release (i.e. WM_CAPTURECHANGED)
i think this might need to be in the parent WndProc anyways
refer to the DivWin2 example i linked earlier
in any case....
the effect you are seeing is due to the fact that the parent window is not being updated when the divider moves
i think moving the capture code to the parent WndProc can help fix that problem
thanks dedndave, I fixed that issue with Windows XP, as you said, it was InitCommonControls. :t
It's curious but I solved the problem using InvalidateRect. :biggrin: I'm not sure if it's the right way thou...
Added the project in case it is useful for someone else.