/** * Creates the Rexx dialog control object that represents the underlying Windows * dialog control. * * The control object can, almost, be created entirely from within the C / C++ * environment. A method context and the Rexx parent dialog are needed. * * @param c * @param hControl * @param hDlg * @param id * @param controlType * @param self * @param isCategoryDlg * @param putInBag * * @return RexxObjectPtr */ RexxObjectPtr createRexxControl(RexxMethodContext *c, HWND hControl, HWND hDlg, uint32_t id, oodControl_t controlType, RexxObjectPtr self, bool isCategoryDlg, bool putInBag) { RexxObjectPtr result = TheNilObj; // Check if the Rexx control object has already been instantiated. RexxObjectPtr rxControl = (RexxObjectPtr)getWindowPtr(hControl, GWLP_USERDATA); if ( rxControl != NULLOBJECT ) { // Okay, this specific control has already had a control object // instantiated to represent it. We return this object. result = rxControl; goto out; } // No pointer is stored in the user data area, so no control object has been // instantiated for this specific control, yet. We instantiate one now and // then store the object in the user data area of the control window. PNEWCONTROLPARAMS pArgs = (PNEWCONTROLPARAMS)malloc(sizeof(NEWCONTROLPARAMS)); if ( pArgs == NULL ) { outOfMemoryException(c->threadContext); goto out; } RexxClassObject controlCls = oodClass4controlType(c, controlType); if ( controlCls == NULLOBJECT ) { goto out; } pArgs->isCatDlg = isCategoryDlg; pArgs->controlType = controlType; pArgs->hwnd = hControl; pArgs->hwndDlg = hDlg; pArgs->id = id; pArgs->parentDlg = self; rxControl = c->SendMessage1(controlCls, "NEW", c->NewPointer(pArgs)); free(pArgs); if ( rxControl != NULLOBJECT && rxControl != TheNilObj ) { result = rxControl; setWindowPtr(hControl, GWLP_USERDATA, (LONG_PTR)result); if ( putInBag ) { c->SendMessage1(self, "PUTCONTROL", result); } } out: return result; }
LRESULT __stdcall pxWindowNative::windowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { int mouseButtonShift = 0; pxWindowNative* w; #ifndef WINCE if (msg == WM_NCCREATE) #else if (msg == WM_CREATE) #endif { CREATESTRUCT *cs = (CREATESTRUCT*)lParam; // ::SetProp(hWnd, _T("wnWindow"), (HANDLE)cs->lpCreateParams); setWindowPtr(hWnd, cs->lpCreateParams); w = (pxWindowNative*)cs->lpCreateParams; w->mWindow = hWnd; } else w = (pxWindowNative*)getWindowPtr(hWnd); bool consumed = false; if (w) { pxEventNativeDesc e; e.wnd = hWnd; e.msg = msg; e.wParam = wParam; e.lParam = lParam; w->onEvent(e, consumed); if (consumed) { // ick if (e.msg == WM_SETCURSOR) return 1; else return 0; } // re resolve the window ptr since we have destroyed it w = (pxWindowNative*)getWindowPtr(hWnd); if (w) { switch(msg) { // Special case code to handle the "fake" close button in the form // of an OK button on win mobile #ifdef MOBILE case WM_COMMAND: { unsigned int wmId = LOWORD(wParam); unsigned int wmEvent = HIWORD(wParam); // Parse the menu selections: switch (wmId) { case IDOK: SendMessage (w->mWindow, WM_CLOSE, 0, 0); break; default: return DefWindowProc(w->mWindow, msg, wParam, lParam); } } break; #endif #if 1 case WM_CREATE: // We have to retry setting the animation timer if it happened to early // after creation w->onCreate(); PostMessage(hWnd, WM_DEFERREDCREATE, 0, 0); break; case WM_DEFERREDCREATE: //w->onCreate(); if (w->mAnimationFPS) w->setAnimationFPS(w->mAnimationFPS); break; case WM_CLOSE: w->onCloseRequest(); return 0; break; case WM_DESTROY: w->onClose(); //SetProp(hWnd, _T("wnWindow"), NULL); #ifdef WINCE setWindowPtr(hWnd, NULL); #endif break; #ifndef WINCE case WM_NCDESTROY: setWindowPtr(hWnd, NULL); break; #endif case WM_RBUTTONDOWN: mouseButtonShift++; case WM_MBUTTONDOWN: mouseButtonShift++; case WM_LBUTTONDOWN: { #if 1 SetCapture(w->mWindow); unsigned long flags = 1 << mouseButtonShift; if (wParam & MK_CONTROL) flags |= PX_MOD_CONTROL; if (wParam & MK_SHIFT) flags |= PX_MOD_SHIFT; if (GetKeyState(VK_MENU) < 0) flags |= PX_MOD_ALT; w->onMouseDown(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), flags); #endif } break; case WM_RBUTTONUP: mouseButtonShift++; case WM_MBUTTONUP: mouseButtonShift++; case WM_LBUTTONUP: { #if 1 ReleaseCapture(); unsigned long flags = 1 << mouseButtonShift; if (wParam & MK_CONTROL) flags |= PX_MOD_CONTROL; if (wParam & MK_SHIFT) flags |= PX_MOD_SHIFT; if (GetKeyState(VK_MENU) < 0) flags |= PX_MOD_ALT; w->onMouseUp(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), flags); #endif } break; case WM_MOUSEMOVE: #if 1 #ifndef WINCE if (!w->mTrackMouse) { TRACKMOUSEEVENT tme; tme.cbSize = sizeof(TRACKMOUSEEVENT); tme.dwFlags = TME_LEAVE; tme.hwndTrack = hWnd; if (TrackMouseEvent(&tme)) { w->mTrackMouse = true; } } #endif w->onMouseMove(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); #endif break; #ifndef WINCE case WM_MOUSELEAVE: w->mTrackMouse = false; w->onMouseLeave(); break; #endif case WM_TIMER: // Should filter this to a single id w->onAnimationTimer(); break; case WM_KEYDOWN: case WM_SYSKEYDOWN: { unsigned long flags = 0; if (GetKeyState(VK_SHIFT) & 0x8000) { flags |= PX_MOD_SHIFT; } if (GetKeyState(VK_CONTROL) & 0x8000) { flags |= PX_MOD_CONTROL; } if (GetKeyState(VK_MENU) & 0x8000) { flags |= PX_MOD_ALT; } w->onKeyDown((int)wParam, flags); } break; case WM_KEYUP: case WM_SYSKEYUP: { unsigned long flags = 0; if (GetKeyState(VK_SHIFT) & 0x8000) { flags |= PX_MOD_SHIFT; } if (GetKeyState(VK_CONTROL) & 0x8000) { flags |= PX_MOD_CONTROL; } if (GetKeyState(VK_MENU) & 0x8000) { flags |= PX_MOD_ALT; } w->onKeyUp((int)wParam, flags); } break; case WM_PAINT: #if 1 { PAINTSTRUCT ps; HDC dc = BeginPaint(w->mWindow, &ps); w->onDraw(dc); EndPaint(w->mWindow, &ps); return 0; } #endif break; case WM_SIZE: { w->onSize(LOWORD(lParam), HIWORD(lParam)); } break; case WM_ERASEBKGND: { #if 0 PAINTSTRUCT ps; HDC dc = BeginPaint(w->mWindow, &ps); w->onDraw(dc); EndPaint(w->mWindow, &ps); #endif } return 0; break; case WM_SYNCHRONIZEDMESSAGE: { synchronizedMessage *m = (synchronizedMessage*)lParam; w->onSynchronizedMessage(m->messageName, m->p1); } break; #endif } } } return DefWindowProc(hWnd, msg, wParam, lParam); }
pxWindowNative::~pxWindowNative() { setWindowPtr(mWindow, NULL); }