scroll bar woes (windows programming)

Started by
9 comments, last by Dead Eye 19 years, 1 month ago
I'm trying to add scroll bars to my program by using the WS_VSCROLL and WS_HSCROLL on some of my windows. However, it seems that whenever I hold the mouse on the "thumb slider" or hold down one of the arrow buttons on the scroll bar, the scroll bar hijacks my program and doesn't allow anything else to happen. Animations stop (except the sliding animation of the scrollbar itself), input is ignored, and window messages don't get processed...in other words my main loop isn't looping. How do I get scroll bars to be nice, allowing input while they are active? I'm using visual c++ 6.0. Thanks in advance for any help.
Advertisement
Post your code in WM_XSCROLL. Windows doesn't hijack
the message loop (it doesn't enter a scroll loop) for
scroll bars as it does with menus, so my guess is
you're doing something wrong in WM_XSCROLL. Can't
really tell without seeing some code. My WM_XSCROLL
code is pretty much always consistent... 1.) set
my scroll variables, 2.) adjust (clamp) scroll
variables, 3.) repaint window. 4.) return.
Sure, here is my WM_XSCROLL handler

case WM_HSCROLL:{	SCROLLINFO si;	si.cbSize = sizeof(SCROLLINFO);	si.fMask = SIF_POS;	GetScrollInfo(hwnd, SB_HORZ, &si);	if(LOWORD(wParam)==SB_LINERIGHT) si.nPos++;	if(LOWORD(wParam)==SB_LINELEFT)	si.nPos--;	if(LOWORD(wParam)==SB_THUMBPOSITION) si.nPos = HIWORD(wParam);	if(LOWORD(wParam)==SB_THUMBTRACK) si.nPos = HIWORD(wParam);	SetScrollInfo(hwnd, SB_HORZ, &si, true);	break;}case WM_VSCROLL:{	SCROLLINFO si;	si.cbSize = sizeof(SCROLLINFO);	si.fMask = SIF_POS;	GetScrollInfo(hwnd, SB_VERT, &si);	if(LOWORD(wParam)==SB_LINEDOWN) si.nPos++;	if(LOWORD(wParam)==SB_LINEUP)	si.nPos--;	if(LOWORD(wParam)==SB_THUMBPOSITION) si.nPos = HIWORD(wParam);	if(LOWORD(wParam)==SB_THUMBTRACK) si.nPos = HIWORD(wParam);	SetScrollInfo(hwnd, SB_VERT, &si, true);	break;}


I'm not sure I should have to manually "SetScrollInfo" the new values, but the scroll bars don't move otherwise.
Ahh, it turns out the scroll bars are not the real culprit. The same thing happens when I click on the resize-border, or the bar at the top of the window.

The only unusual thing I can think of is that I have a parent window with two child windows that all use the same WNDCLASS, and the same message handler. Could that be the cause of my problems?
can you post your window procedure? in general you usually
do create different window classes for parent/children,
but it's not a bad thing if the windows do the same things,
but just have different window styles. but yes, if your
window proc has static data, with multiple windows accessing
it, you can run into trouble (you can use the window extra
bytes from the WNDCLASS struct instead to store data unique
to each window).
I've actually already posted 90% of my WNDPROC :)

But maybe I'm doing something terribly obvious causing this.

LRESULT CALLBACK myd3d::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){	switch(msg)	{		case WM_DESTROY:			PostQuitMessage(0);			break;		case WM_KEYDOWN:			if(wParam == VK_ESCAPE)				DestroyWindow(hwnd);			break;		case WM_HSCROLL:		{			SCROLLINFO si;			si.cbSize = sizeof(SCROLLINFO);			si.fMask = SIF_POS;			GetScrollInfo(hwnd, SB_HORZ, &si);			if(LOWORD(wParam)==SB_LINERIGHT) si.nPos++;			if(LOWORD(wParam)==SB_LINELEFT)	si.nPos--;			if(LOWORD(wParam)==SB_THUMBPOSITION) si.nPos = HIWORD(wParam);			if(LOWORD(wParam)==SB_THUMBTRACK) si.nPos = HIWORD(wParam);			SetScrollInfo(hwnd, SB_HORZ, &si, true);			break;		}		case WM_VSCROLL:		{			SCROLLINFO si;			si.cbSize = sizeof(SCROLLINFO);			si.fMask = SIF_POS;			GetScrollInfo(hwnd, SB_VERT, &si);			if(LOWORD(wParam)==SB_LINEDOWN) si.nPos++;			if(LOWORD(wParam)==SB_LINEUP)	si.nPos--;			if(LOWORD(wParam)==SB_THUMBPOSITION) si.nPos = HIWORD(wParam);			if(LOWORD(wParam)==SB_THUMBTRACK) si.nPos = HIWORD(wParam);			SetScrollInfo(hwnd, SB_VERT, &si, true);			break;		} 	}	return(DefWindowProc(hwnd, msg, wParam, lParam));}



My main loop might be useful as well.
while(msg.message != WM_QUIT)	{		if(PeekMessage(&msg, 0, 0, 0, PM_REMOVE))		{			TranslateMessage(&msg);			DispatchMessage(&msg);		}	//	else	//	{			float currTime = (float)timeGetTime();			float timeDelta = (currTime - lastTime) * 0.001f;			ptr_display(timeDelta);			lastTime = currTime;	//	}	}	return(msg.wParam);


The program behaves the same way whether I have the else commented out or not.
Having done a little more testing, I am now even more thoroughly confused. I set it to display one message box every time it handles a WM_VSCROLL message, and a different message box every time it iterates through the main loop.

And, using the thumb-bar or holding the mouse down on one of the scroll bar arrows, I handle more vertical scroll bar messages than I do iterations through the main loop.

I am using if(peekmessage()), so how can I possibly handle more that one message per loop iteration??
I doubt it solves your problem but in general when you handle a message your windowprov should return 0 and not DefWindowProc.
Thanks, I changed the breaks to return(0)'s, but I'm still having the same problem.
Well, the WM_XSCROLL messages never even appear in my main loop. The scroll bars must be off doing their own thing that I can't do anything about.

If someone knows how to fix this "modal" (not sure that's the right word) behavior of scroll bars I'd be grateful...but for now I'll just use createwindow to get my scroll bars.


edit: Forget it, windows created with the "scroll bar" class do exactly the same thing. I get ripped out of my main loop whenever a window owned by the same process is being moved, activated, selected, etc.

Perhaps it is time for me to look into multithreading.

[Edited by - bjle on March 4, 2005 4:17:10 PM]

This topic is closed to new replies.

Advertisement