static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lParam) { int useDefWindowProc = 0; JNIEnv *env = NULL; jobject window = NULL; BOOL isKeyDown = FALSE; WindowUserData * wud; #if defined(UNDER_CE) || _MSC_VER <= 1200 wud = (WindowUserData *) GetWindowLong(wnd, GWL_USERDATA); #else wud = (WindowUserData *) GetWindowLongPtr(wnd, GWLP_USERDATA); #endif if(NULL==wud) { return DefWindowProc(wnd, message, wParam, lParam); } env = wud->jenv; window = wud->jinstance; if (NULL==window || NULL==env) { return DefWindowProc(wnd, message, wParam, lParam); } // DBG_PRINT("*** WindowsWindow: window %p -> %p, 0x%X %d/%d\n", wnd, window, message, (int)LOWORD(lParam), (int)HIWORD(lParam)); switch (message) { // // The signal pipeline for destruction is: // Java::DestroyWindow(wnd) _or_ window-close-button -> // WM_CLOSE -> Java::windowDestroyNotify -> W_DESTROY -> Java::windowDestroyed -> // Java::CleanupWindowResources() case WM_CLOSE: (*env)->CallVoidMethod(env, window, windowDestroyNotifyID); break; case WM_DESTROY: { #if defined(UNDER_CE) || _MSC_VER <= 1200 SetWindowLong(wnd, GWL_USERDATA, (intptr_t) NULL); #else SetWindowLongPtr(wnd, GWLP_USERDATA, (intptr_t) NULL); #endif free(wud); wud=NULL; (*env)->CallVoidMethod(env, window, windowDestroyedID); (*env)->DeleteGlobalRef(env, window); } break; case WM_SYSCHAR: useDefWindowProc = WmChar(env, window, wParam, LOWORD(lParam), HIWORD(lParam), FALSE); break; case WM_CHAR: useDefWindowProc = WmChar(env, window, wParam, LOWORD(lParam), HIWORD(lParam), TRUE); break; case WM_KEYDOWN: useDefWindowProc = WmKeyDown(env, window, wParam, LOWORD(lParam), HIWORD(lParam), FALSE); break; case WM_KEYUP: useDefWindowProc = WmKeyUp(env, window, wParam, LOWORD(lParam), HIWORD(lParam), FALSE); break; case WM_SIZE: WmSize(env, wnd, window, (UINT)wParam); break; case WM_SETTINGCHANGE: if (wParam == SPI_SETNONCLIENTMETRICS) { // make sure insets are updated, we don't need to resize the window // because the size of the client area doesn't change (void)UpdateInsets(env, wnd, window); } else { useDefWindowProc = 1; } break; case WM_LBUTTONDOWN: (*env)->CallVoidMethod(env, window, sendMouseEventID, (jint) EVENT_MOUSE_PRESSED, GetModifiers(), (jint) LOWORD(lParam), (jint) HIWORD(lParam), (jint) 1, (jint) 0); useDefWindowProc = 1; break; case WM_LBUTTONUP: (*env)->CallVoidMethod(env, window, sendMouseEventID, (jint) EVENT_MOUSE_RELEASED, GetModifiers(), (jint) LOWORD(lParam), (jint) HIWORD(lParam), (jint) 1, (jint) 0); useDefWindowProc = 1; break; case WM_MBUTTONDOWN: (*env)->CallVoidMethod(env, window, sendMouseEventID, (jint) EVENT_MOUSE_PRESSED, GetModifiers(), (jint) LOWORD(lParam), (jint) HIWORD(lParam), (jint) 2, (jint) 0); useDefWindowProc = 1; break; case WM_MBUTTONUP: (*env)->CallVoidMethod(env, window, sendMouseEventID, (jint) EVENT_MOUSE_RELEASED, GetModifiers(), (jint) LOWORD(lParam), (jint) HIWORD(lParam), (jint) 2, (jint) 0); useDefWindowProc = 1; break; case WM_RBUTTONDOWN: (*env)->CallVoidMethod(env, window, sendMouseEventID, (jint) EVENT_MOUSE_PRESSED, GetModifiers(), (jint) LOWORD(lParam), (jint) HIWORD(lParam), (jint) 3, (jint) 0); useDefWindowProc = 1; break; case WM_RBUTTONUP: (*env)->CallVoidMethod(env, window, sendMouseEventID, (jint) EVENT_MOUSE_RELEASED, GetModifiers(), (jint) LOWORD(lParam), (jint) HIWORD(lParam), (jint) 3, (jint) 0); useDefWindowProc = 1; break; case WM_MOUSEMOVE: (*env)->CallVoidMethod(env, window, sendMouseEventID, (jint) EVENT_MOUSE_MOVED, GetModifiers(), (jint) LOWORD(lParam), (jint) HIWORD(lParam), (jint) 0, (jint) 0); useDefWindowProc = 1; break; case WM_MOUSEWHEEL: { // need to convert the coordinates to component-relative int x = GET_X_LPARAM(lParam); int y = GET_Y_LPARAM(lParam); POINT eventPt; eventPt.x = x; eventPt.y = y; ScreenToClient(wnd, &eventPt); (*env)->CallVoidMethod(env, window, sendMouseEventID, (jint) EVENT_MOUSE_WHEEL_MOVED, GetModifiers(), (jint) eventPt.x, (jint) eventPt.y, (jint) 0, (jint) (GET_WHEEL_DELTA_WPARAM(wParam)/120.0f)); useDefWindowProc = 1; break; } case WM_SETFOCUS: (*env)->CallVoidMethod(env, window, focusChangedID, (jlong)wParam, JNI_TRUE); useDefWindowProc = 1; break; case WM_KILLFOCUS: (*env)->CallVoidMethod(env, window, focusChangedID, (jlong)wParam, JNI_FALSE); useDefWindowProc = 1; break; case WM_MOVE: DBG_PRINT("*** WindowsWindow: WM_MOVE window %p, %d/%d\n", wnd, (int)LOWORD(lParam), (int)HIWORD(lParam)); (*env)->CallVoidMethod(env, window, positionChangedID, (jint)LOWORD(lParam), (jint)HIWORD(lParam)); useDefWindowProc = 1; break; case WM_PAINT: { RECT r; if (GetUpdateRect(wnd, &r, FALSE)) { if ((r.right-r.left) > 0 && (r.bottom-r.top) > 0) { (*env)->CallVoidMethod(env, window, sendPaintEventID, 0, r.left, r.top, r.right-r.left, r.bottom-r.top); } ValidateRect(wnd, &r); useDefWindowProc = 0; } else { useDefWindowProc = 1; } break; } case WM_ERASEBKGND: // ignore erase background useDefWindowProc = 0; break; // FIXME: generate EVENT_MOUSE_ENTERED, EVENT_MOUSE_EXITED default: useDefWindowProc = 1; } if (useDefWindowProc) return DefWindowProc(wnd, message, wParam, lParam); return 0; }
LRESULT SWindow::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { if(HWindow == NULL) HWindow = hwnd; Org_Mes OrgMes; OrgMes.AutoDelete = AutoDelete; OrgMes.ControlMode = ControlMode; OrgMes.HWindow = hwnd; OrgMes.OriginalWndProc = OriginalWndProc; OrgMes.uMsg = uMsg; OrgMes.wParam = wParam; OrgMes.lParam = lParam; OrgMes.ExecMessage = false; OrgMes.RetProcCode = 0; bool RetMessage = false; LRESULT RetCode; switch(uMsg) { case WM_COMMAND: WmCommand(&OrgMes, HIWORD(wParam), LOWORD(wParam), reinterpret_cast<HWND>(lParam)); break; case WM_SYSCOMMAND: WmSysCommand(&OrgMes, static_cast<UINT>(wParam), GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); break; case WM_APPCOMMAND: RetMessage = true; RetCode = WmAppCommand(&OrgMes, lParam); break; case WM_NOTIFY: RetMessage = true; RetCode = WmNotify(&OrgMes, static_cast<UINT>(wParam), reinterpret_cast<LPNMHDR>(lParam)); break; case WM_SHOWWINDOW: WmShowWindow(&OrgMes, wParam, lParam); break; case WM_SIZE: WmSize(&OrgMes, static_cast<UINT>(wParam), LOWORD(lParam), HIWORD(lParam)); break; case WM_MOVE: WmMove(&OrgMes, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); break; case WM_PAINT: WmPaint(&OrgMes); break; case WM_MOUSEMOVE: WmMouseMove(&OrgMes, static_cast<UINT>(wParam), GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); break; case WM_LBUTTONDOWN: WmLButtonDown(&OrgMes, static_cast<UINT>(wParam), GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); break; case WM_RBUTTONDOWN: WmRButtonDown(&OrgMes, static_cast<UINT>(wParam), GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); break; case WM_LBUTTONUP: WmLButtonUp(&OrgMes, static_cast<UINT>(wParam), GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); break; case WM_RBUTTONUP: WmRButtonUp(&OrgMes, static_cast<UINT>(wParam), GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); break; case WM_LBUTTONDBLCLK: WmLButtonDblClk(&OrgMes, static_cast<UINT>(wParam), GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); break; case WM_RBUTTONDBLCLK: WmRButtonDblClk(&OrgMes, static_cast<UINT>(wParam), GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); break; case WM_DROPFILES: WmDropFiles(&OrgMes, reinterpret_cast<HDROP>(wParam)); break; case WM_KEYDOWN: WmKeyDown(&OrgMes, static_cast<int>(wParam), static_cast<UINT>(lParam)); break; case WM_CHAR: WmChar(&OrgMes, static_cast<TCHAR>(wParam), static_cast<UINT>(lParam)); break; case WM_CONTEXTMENU: WmContextMenu( &OrgMes, reinterpret_cast<HWND>(wParam), GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); break; case WM_MENUSELECT: WmMenuSelect(&OrgMes, LOWORD(wParam), HIWORD(wParam), reinterpret_cast<HMENU>(lParam)); break; case WM_DRAWITEM: RetMessage = true; RetCode = WmDrawItem( &OrgMes, static_cast<int>(wParam), reinterpret_cast<LPDRAWITEMSTRUCT>(lParam)); break; case WM_TIMER: WmTimer(&OrgMes, static_cast<UINT>(wParam), reinterpret_cast<TIMERPROC*>(lParam)); break; case WM_ACTIVATE: WmActivate(&OrgMes, LOWORD(wParam), HIWORD(wParam) != 0, reinterpret_cast<HWND>(lParam)); break; case WM_SETCURSOR: WmSetCursor(&OrgMes, reinterpret_cast<HWND>(wParam), LOWORD(lParam), HIWORD(lParam)); break; case WM_SETFOCUS: WmSetFocus(&OrgMes, reinterpret_cast<HWND>(wParam)); break; case WM_KILLFOCUS: WmKillFocus(&OrgMes, reinterpret_cast<HWND>(wParam)); break; /* case WM_CTLCOLORDLG: RetMessage = true; RetCode = reinterpret_cast<LRESULT> (WmCtlColorDlg(&OrgMes, reinterpret_cast<HWND>(lParam), reinterpret_cast<HDC>(wParam))); break; case WM_CTLCOLORSTATIC: RetMessage = true; RetCode = reinterpret_cast<LRESULT> (WmCtlColorStatic(&OrgMes, reinterpret_cast<HWND>(lParam), reinterpret_cast<HDC>(wParam))); break; case WM_CTLCOLOREDIT: RetMessage = true; RetCode = reinterpret_cast<LRESULT> (WmCtlColorEdit(&OrgMes, reinterpret_cast<HWND>(lParam), reinterpret_cast<HDC>(wParam))); break; case WM_CTLCOLORLISTBOX: RetMessage = true; RetCode = reinterpret_cast<LRESULT> (WmCtlColorListBox(&OrgMes, reinterpret_cast<HWND>(lParam), reinterpret_cast<HDC>(wParam))); break; case WM_ERASEBKGND: RetMessage = true; RetCode = WmEraseBkGnd(&OrgMes, reinterpret_cast<HDC>(wParam)); break; */ case WM_CREATE: RetMessage = true; RetCode = WmCreate(&OrgMes, reinterpret_cast<LPCREATESTRUCT>(lParam)); SetupWindow(); break; case WM_INITDIALOG: RetMessage = true; RetCode = WmInitDialog(&OrgMes, reinterpret_cast<HWND>(wParam), static_cast<LONG>(lParam)); break; case WM_CLOSE: WmClose(&OrgMes); break; case WM_DESTROY: WmDestroy(&OrgMes); if(OrgMes.AutoDelete) { SetWindowLongPtr(GWLP_USERDATA, NULL); delete this; } break; case WM_SYSCOLORCHANGE: WmSysColorChange(&OrgMes); break; case WM_QUERYENDSESSION: RetMessage = true; RetCode = WmQueryEndSession(&OrgMes, static_cast<UINT>(wParam)); break; case WM_ENDSESSION: WmEndSession(&OrgMes, wParam != 0); if(OrgMes.AutoDelete && wParam) { SetWindowLongPtr(GWLP_USERDATA, NULL); delete this; } break; default: if((uMsg >= WM_USER) && (uMsg <= 0x7fff)) { RetMessage = true; RetCode = WmUser(&OrgMes, uMsg, wParam, lParam); } else { DefaultProc(&OrgMes); } break; } if(RetMessage == false) { if(OrgMes.OriginalWndProc || (OrgMes.ControlMode == ControlMode_Normal)) { RetCode = OrgMes.ExecMessage ? 0 : OrgMes.RetProcCode; } else { RetCode = OrgMes.ExecMessage; } } return RetCode; }