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:

  1. your window class forwards wm_mousewheel edit control
  2. if control key pressed, edit control ignores wm_mousewheel message , passes defwindowproc.
  3. defwindowproc passes message parent chain (this behavior documented in wm_mousewheel documentation).
  4. 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

Popular posts from this blog

java - Date formats difference between yyyy-MM-dd'T'HH:mm:ss and yyyy-MM-dd'T'HH:mm:ssXXX -

c# - Get rid of xmlns attribute when adding node to existing xml -