c - Why does app terminate for no reason when I scroll the mouse wheel while the control key is pressed? -
when control key down , scroll mouse wheel app terminates no reason. testing on windows xp. happens when control key pressed while scrolling. if control key not pressed while scrolling, doesn't happen. don't know how other operating systems. use code below test this
#include <windows.h> #include <tchar.h> lresult callback wndproc(hwnd hwnd, uint msg, wparam wparam, lparam lparam) { static hwnd hedit = 0; switch(msg) { case wm_create: hedit = createwindowex(ws_ex_clientedge, text("edit"), 0, ws_visible | ws_child | ws_hscroll | ws_vscroll | es_multiline | es_readonly, 0, 0, 0, 0, hwnd, 0, getmodulehandle(0), 0); break; case wm_size: movewindow(hedit, 0, 0, loword(lparam), hiword(lparam), true); break; case wm_mousewheel: sendmessage(hedit, msg, wparam, lparam); break; case wm_destroy: postquitmessage(0); break; default: return defwindowproc(hwnd, msg, wparam, lparam); } return 0; } int winapi _twinmain(hinstance hinstance, hinstance hprevinstance, lptstr lpcmdline, int ncmdshow) { wndclassex wc = {0}; hwnd hwnd; msg msg; wc.cbsize = sizeof wc; wc.hbrbackground = 0; wc.hcursor = loadcursor(0, idc_arrow); wc.hicon = loadicon(0, idi_application); wc.hinstance = hinstance; wc.lpfnwndproc = wndproc; wc.lpszclassname = text("mainclass"); if(!registerclassex(&wc)) return 0; hwnd = createwindowex(0, wc.lpszclassname, text("hello"), ws_overlappedwindow, 40, 20, 400, 200, 0, 0, hinstance, 0); if(!hwnd) return 0; showwindow(hwnd, ncmdshow); while(getmessage(&msg, 0, 0, 0) > 0) { translatemessage(&msg); dispatchmessage(&msg); } return (int)msg.wparam; }
if comment out 3 lines below, , control key pressed while scrolling, doesn't happen
case wm_mousewheel: sendmessage(hedit, msg, wparam, lparam); break;
expanding on said in comment:
- your window class forwards
wm_mousewheel
edit control - if control key pressed, edit control ignores
wm_mousewheel
message , passesdefwindowproc
. defwindowproc
passes message parent chain (this behavior documented inwm_mousewheel
documentation).- your window receives forwarded message , loops step #1
eventually run out of stack , process terminated.
there 3 ways fix this:
the first (and safest) use flag prevent recursive loop; e.g.:
static bool finforwardmsg; // if have multiple windows want make local variable case wm_mousewheel: if (!finforwardmsg) { finforwardmsg = true; sendmessage(hedit, umsg, wparam, lparam); finforwardmsg = false; } break;
the second solution relies on fact edit control looks @ wparam
value see if control key down (it checks shift well, incidentally). internal undocumented behavior , subject change, shouldn't rely on it, should able prevent problem not forwarding original value of wparam
. e.g.:
case wm_mousewheel: sendmessage(hedit, msg, wparam & ~0xffff, lparam); break;
the third solution simplest; since edit control doesn't if shift or control held down, don't forward message in cases:
case wm_mousewheel: if (!(wparam & (mk_shift | mk_control)) sendmessage(hedit, msg, wparam, lparam); break;
Comments
Post a Comment