// /// Functional-style overload // std::pair<TPoint, bool> TDropInfo::DragQueryPoint() const { TPoint p; bool r = DragQueryPoint(p); return std::make_pair(p, r); }
static void Add_File_Events(REBGOB *gob, REBINT flags, HDROP drop) { REBEVT evt; REBINT num; REBINT len; REBINT i; REBCHR* buf; POINT xy; //Get the mouse position DragQueryPoint(drop, &xy); evt.type = EVT_DROP_FILE; evt.flags = (u8) (flags | (1<<EVF_HAS_XY)); evt.info = 0; evt.data = xy.x | xy.y<<16; num = DragQueryFile(drop, -1, NULL, 0); for (i = 0; i < num; i++){ len = DragQueryFile(drop, i, NULL, 0); buf = OS_Make(len+1); DragQueryFile(drop, i, buf, len+1); //Reb_Print("DROP: %s", buf); buf[len] = 0; // ?! convert to REBOL format? E.g.: evt.ser = OS_To_REBOL_File(buf, &len); OS_Free(buf); if (!Reb_Event(&evt)) break; // queue is full } }
void HandleFiles(WPARAM wParam) { // DragQueryFile() takes a LPWSTR for the name so we need a TCHAR string TCHAR szName[MAX_PATH]; // Here we cast the wParam as a HDROP handle to pass into the next functions HDROP hDrop = (HDROP)wParam; POINT pt; DragQueryPoint(hDrop, &pt); //printf("%i %i \n", pt.x, pt.y); ofDragInfo info; info.position.x = pt.x; info.position.y = pt.y; // This functions has a couple functionalities. If you pass in 0xFFFFFFFF in // the second parameter then it returns the count of how many filers were drag // and dropped. Otherwise, the function fills in the szName string array with // the current file being queried. int count = DragQueryFile(hDrop, 0xFFFFFFFF, szName, MAX_PATH); // Here we go through all the files that were drag and dropped then display them for(int i = 0; i < count; i++) { // Grab the name of the file associated with index "i" in the list of files dropped. // Be sure you know that the name is attached to the FULL path of the file. DragQueryFile(hDrop, i, szName, MAX_PATH); wchar_t * s = szName; char dfault = '?'; const std::locale& loc = std::locale(); std::ostringstream stm; while( *s != L'\0' ) { stm << std::use_facet< std::ctype<wchar_t> >( loc ).narrow( *s++, dfault ); } info.files.push_back(string(stm.str())); //toUTF8(udispName, dispName); // Bring up a message box that displays the current file being processed //MessageBox(GetForegroundWindow(), szName, L"Current file received", MB_OK); } // Finally, we destroy the HDROP handle so the extra memory // allocated by the application is released. DragFinish(hDrop); ofAppPtr->dragEvent(info); }
void TeamsWindow::DoDrag( WORD hDragInfo ) { char filename[128]; unsigned short usNumOfFiles; unsigned short i; short index; POINT pt; BOOL drop_ok = FALSE; usNumOfFiles = DragQueryFile((HDROP) hDragInfo, -1, NULL, 0); if (DragQueryPoint((HDROP) hDragInfo, &pt)) { short x = pt.x; short y = pt.y; x /= usMiniCarWidth; y /= usMiniCarHeight; index = (y * TEAMS_NUM_X) + x; for (i = 0; i < usNumOfFiles; i++) { (void) DragQueryFile((HDROP) hDragInfo, i, filename, sizeof(filename)); ASSERT(index >= 0 && index < GP_EXE_NUM_TEAMS); if (index >= 0 && index < GP_EXE_NUM_TEAMS) { FrameActiveTeam(index); usSelectedTeam = index; if (SendMessage(Parent(), IDE_DESIGN_TEAM_SELECT, usSelectedTeam, 0L)) { UpdateMemoryImage(); } (void) SendMessage(Parent(), IDE_CBAR_TEAM_SELECT, usSelectedTeam, 0L); /* ** Now load new car colours. */ drop_ok = (BOOL) SendMessage(Parent(), IDE_DESIGN_LOAD, 0, (LONG) (void *) filename); UpdateMemoryImage(); } /* ** Wrap to next time on a multi-file drop. */ if (drop_ok && ++index >= GP_EXE_NUM_TEAMS) { index = 0; } } } }
void CMediaWnd::OnDropFiles(HDROP hDropInfo) { if ( hDropInfo != NULL ) { CStringList oFileList; TCHAR szFileName[MAX_PATH + 1]; UINT nFiles = DragQueryFile( hDropInfo, (UINT)-1, NULL, 0 ); for( UINT nNames = 0; nNames < nFiles; nNames++ ) { ZeroMemory( szFileName, MAX_PATH + 1 ); DragQueryFile( hDropInfo, nNames, (LPTSTR)szFileName, MAX_PATH + 1 ); oFileList.AddTail( szFileName ); } CPoint oPoint; POINT pt; DragQueryPoint( hDropInfo, &pt ); oPoint.SetPoint( pt.x, pt.y ); OnDropFiles( oFileList, oPoint, TRUE ); } }
/*=============================================================== * WMHandler::onDropFiles_() * ドロップファイルの定型處理を行ひ、ユーザ實裝部を呼び出す */ void urania::WMHandler::onDropFiles_(urania::Window* win, WPARAM wp) { HDROP hd = (HDROP)wp; POINT p; DragQueryPoint(hd, &p); std::vector<std::wstring> astr; wchar_t temp[MAX_PATH]; int n = DragQueryFile(hd, 0xffffffff, nullptr, 0); for (int i = 0; i < n; i++) { DragQueryFile(hd, i, temp, MAX_PATH); astr.push_back(temp); } DragFinish(hd); // ユーザがサブクラスでオーバーライドするハンドラを呼び出し onDropFiles(win, astr, p.x, p.y); }
void CVirtualTreeCtrl::OnDropFiles(HDROP hDropInfo) { CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd()); INDEX ctFiles = DragQueryFile( hDropInfo, 0xFFFFFFFF, NULL, 0); // get dropped coordinates CPoint point; DragQueryPoint( hDropInfo, &point); CVirtualTreeNode *pVTNDst = ItemForCoordinate(point); if( pVTNDst!=NULL) { for( INDEX i=0; i<ctFiles; i++) { char chrFile[ 256]; DragQueryFile( hDropInfo, i, chrFile, 256); CTString strAddr = CTString(chrFile); if( strAddr != "") { CVirtualTreeNode *pVTNSrc; strAddr.ScanF("VTN%d", &pVTNSrc); if(pVTNSrc==pVTNDst) return; pVTNSrc->MoveToDirectory( pVTNDst); // delete all items DeleteAllItems(); m_pBrowser->AddDirectoryRecursiv( &m_pBrowser->m_VirtualTree, TVI_ROOT); // Fill CTreeCtrl using recursion SortChildren( NULL); SelectItem( (HTREEITEM) pVTNSrc->vtn_Handle); m_pBrowser->m_bVirtualTreeChanged = TRUE; m_pBrowser->OpenSelectedDirectory(); } } } CTreeCtrl::OnDropFiles(hDropInfo); }
// Window callback function (handles window events) // static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { _GLFWwindow* window = (_GLFWwindow*) GetWindowLongPtrW(hWnd, 0); switch (uMsg) { case WM_NCCREATE: { CREATESTRUCTW* cs = (CREATESTRUCTW*) lParam; SetWindowLongPtrW(hWnd, 0, (LONG_PTR) cs->lpCreateParams); break; } case WM_SETFOCUS: { if (window->cursorMode != GLFW_CURSOR_NORMAL) _glfwPlatformApplyCursorMode(window); if (window->monitor && window->autoIconify) enterFullscreenMode(window); _glfwInputWindowFocus(window, GL_TRUE); return 0; } case WM_KILLFOCUS: { if (window->cursorMode != GLFW_CURSOR_NORMAL) restoreCursor(window); if (window->monitor && window->autoIconify) { _glfwPlatformIconifyWindow(window); leaveFullscreenMode(window); } _glfwInputWindowFocus(window, GL_FALSE); return 0; } case WM_SYSCOMMAND: { switch (wParam & 0xfff0) { case SC_SCREENSAVE: case SC_MONITORPOWER: { if (window->monitor) { // We are running in full screen mode, so disallow // screen saver and screen blanking return 0; } else break; } // User trying to access application menu using ALT? case SC_KEYMENU: return 0; } break; } case WM_CLOSE: { _glfwInputWindowCloseRequest(window); return 0; } case WM_KEYDOWN: case WM_SYSKEYDOWN: { const int scancode = (lParam >> 16) & 0x1ff; const int key = translateKey(wParam, lParam); if (key == _GLFW_KEY_INVALID) break; _glfwInputKey(window, key, scancode, GLFW_PRESS, getKeyMods()); break; } case WM_CHAR: { _glfwInputChar(window, (unsigned int) wParam, getKeyMods(), GL_TRUE); return 0; } case WM_SYSCHAR: { _glfwInputChar(window, (unsigned int) wParam, getKeyMods(), GL_FALSE); return 0; } case WM_UNICHAR: { // This message is not sent by Windows, but is sent by some // third-party input method engines if (wParam == UNICODE_NOCHAR) { // Returning TRUE here announces support for this message return TRUE; } _glfwInputChar(window, (unsigned int) wParam, getKeyMods(), GL_TRUE); return FALSE; } case WM_KEYUP: case WM_SYSKEYUP: { const int mods = getKeyMods(); const int scancode = (lParam >> 16) & 0x1ff; const int key = translateKey(wParam, lParam); if (key == _GLFW_KEY_INVALID) break; if (wParam == VK_SHIFT) { // Release both Shift keys on Shift up event, as only one event // is sent even if both keys are released _glfwInputKey(window, GLFW_KEY_LEFT_SHIFT, scancode, GLFW_RELEASE, mods); _glfwInputKey(window, GLFW_KEY_RIGHT_SHIFT, scancode, GLFW_RELEASE, mods); } else if (wParam == VK_SNAPSHOT) { // Key down is not reported for the print screen key _glfwInputKey(window, key, scancode, GLFW_PRESS, mods); _glfwInputKey(window, key, scancode, GLFW_RELEASE, mods); } else _glfwInputKey(window, key, scancode, GLFW_RELEASE, mods); break; } case WM_LBUTTONDOWN: case WM_RBUTTONDOWN: case WM_MBUTTONDOWN: case WM_XBUTTONDOWN: { const int mods = getKeyMods(); SetCapture(hWnd); if (uMsg == WM_LBUTTONDOWN) _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_LEFT, GLFW_PRESS, mods); else if (uMsg == WM_RBUTTONDOWN) _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_RIGHT, GLFW_PRESS, mods); else if (uMsg == WM_MBUTTONDOWN) _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_MIDDLE, GLFW_PRESS, mods); else { if (HIWORD(wParam) == XBUTTON1) _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_4, GLFW_PRESS, mods); else if (HIWORD(wParam) == XBUTTON2) _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_5, GLFW_PRESS, mods); return TRUE; } return 0; } case WM_LBUTTONUP: case WM_RBUTTONUP: case WM_MBUTTONUP: case WM_XBUTTONUP: { const int mods = getKeyMods(); ReleaseCapture(); if (uMsg == WM_LBUTTONUP) _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_LEFT, GLFW_RELEASE, mods); else if (uMsg == WM_RBUTTONUP) _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_RIGHT, GLFW_RELEASE, mods); else if (uMsg == WM_MBUTTONUP) _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_MIDDLE, GLFW_RELEASE, mods); else { if (HIWORD(wParam) == XBUTTON1) _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_4, GLFW_RELEASE, mods); else if (HIWORD(wParam) == XBUTTON2) _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_5, GLFW_RELEASE, mods); return TRUE; } return 0; } case WM_MOUSEMOVE: { const int x = GET_X_LPARAM(lParam); const int y = GET_Y_LPARAM(lParam); if (window->cursorMode == GLFW_CURSOR_DISABLED) { if (_glfw.focusedWindow != window) break; _glfwInputCursorMotion(window, x - window->win32.cursorPosX, y - window->win32.cursorPosY); } else _glfwInputCursorMotion(window, x, y); window->win32.cursorPosX = x; window->win32.cursorPosY = y; if (!window->win32.cursorInside) { TRACKMOUSEEVENT tme; ZeroMemory(&tme, sizeof(tme)); tme.cbSize = sizeof(tme); tme.dwFlags = TME_LEAVE; tme.hwndTrack = window->win32.handle; TrackMouseEvent(&tme); window->win32.cursorInside = GL_TRUE; _glfwInputCursorEnter(window, GL_TRUE); } return 0; } case WM_MOUSELEAVE: { window->win32.cursorInside = GL_FALSE; _glfwInputCursorEnter(window, GL_FALSE); return 0; } case WM_MOUSEWHEEL: { _glfwInputScroll(window, 0.0, (SHORT) HIWORD(wParam) / (double) WHEEL_DELTA); return 0; } case WM_MOUSEHWHEEL: { // This message is only sent on Windows Vista and later // NOTE: The X-axis is inverted for consistency with OS X and X11. _glfwInputScroll(window, -((SHORT) HIWORD(wParam) / (double) WHEEL_DELTA), 0.0); return 0; } case WM_SIZE: { if (_glfw.focusedWindow == window) { if (window->cursorMode == GLFW_CURSOR_DISABLED) updateClipRect(window); } if (!window->win32.iconified && wParam == SIZE_MINIMIZED) { window->win32.iconified = GL_TRUE; _glfwInputWindowIconify(window, GL_TRUE); } else if (window->win32.iconified && (wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED)) { window->win32.iconified = GL_FALSE; _glfwInputWindowIconify(window, GL_FALSE); } _glfwInputFramebufferSize(window, LOWORD(lParam), HIWORD(lParam)); _glfwInputWindowSize(window, LOWORD(lParam), HIWORD(lParam)); return 0; } case WM_MOVE: { if (_glfw.focusedWindow == window) { if (window->cursorMode == GLFW_CURSOR_DISABLED) updateClipRect(window); } // NOTE: This cannot use LOWORD/HIWORD recommended by MSDN, as // those macros do not handle negative window positions correctly _glfwInputWindowPos(window, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); return 0; } case WM_PAINT: { _glfwInputWindowDamage(window); break; } case WM_ERASEBKGND: { return TRUE; } case WM_SETCURSOR: { if (_glfw.focusedWindow == window && LOWORD(lParam) == HTCLIENT) { if (window->cursorMode == GLFW_CURSOR_HIDDEN || window->cursorMode == GLFW_CURSOR_DISABLED) { SetCursor(NULL); return TRUE; } else if (window->cursor) { SetCursor(window->cursor->win32.handle); return TRUE; } } break; } case WM_DEVICECHANGE: { if (DBT_DEVNODES_CHANGED == wParam) { _glfwInputMonitorChange(); return TRUE; } break; } case WM_DWMCOMPOSITIONCHANGED: { if (_glfwIsCompositionEnabled()) { _GLFWwindow* previous = _glfwPlatformGetCurrentContext(); _glfwPlatformMakeContextCurrent(window); _glfwPlatformSwapInterval(0); _glfwPlatformMakeContextCurrent(previous); } // TODO: Restore vsync if compositing was disabled break; } case WM_DROPFILES: { HDROP hDrop = (HDROP) wParam; POINT pt; int i; const int count = DragQueryFileW(hDrop, 0xffffffff, NULL, 0); char** paths = calloc(count, sizeof(char*)); // Move the mouse to the position of the drop DragQueryPoint(hDrop, &pt); _glfwInputCursorMotion(window, pt.x, pt.y); for (i = 0; i < count; i++) { const UINT length = DragQueryFileW(hDrop, i, NULL, 0); WCHAR* buffer = calloc(length + 1, sizeof(WCHAR)); DragQueryFileW(hDrop, i, buffer, length + 1); paths[i] = _glfwCreateUTF8FromWideString(buffer); free(buffer); } _glfwInputDrop(window, count, (const char**) paths); for (i = 0; i < count; i++) free(paths[i]); free(paths); DragFinish(hDrop); return 0; } } return DefWindowProc(hWnd, uMsg, wParam, lParam); }
// // Main Window message handler // LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { NMHDR *hdr; POINT pt; RECT rect; HMENU hMenu; HWND hwndHV = GetActiveHexView(hwnd);//g_hwndHexView; int i; TCITEM tci; MAINWND *mainWnd = (MAINWND *)GetWindowLongPtr(hwnd, 0); switch(msg) { case WM_NCCREATE: if((mainWnd = malloc(sizeof(MAINWND))) == 0) return FALSE; SetWindowLongPtr(hwnd, 0, (LONG_PTR)mainWnd); ZeroMemory(mainWnd, sizeof(MAINWND)); return TRUE; case WM_NCDESTROY: free(mainWnd); return 0; case WM_CREATE: g_hwndMain = hwnd; SetWindowIcon(hwnd, IDI_APP); // create a child-window EDIT control //g_hwndHexView = CreateHexViewCtrl(hwnd); g_hwndTabView = CreateWindow(WC_TABVIEW, TEXT(""), WS_CHILD|WS_VISIBLE,0,0,0,0,hwnd, 0, g_hInstance, 0); g_hwndStatusBar = CreateStatusBar(hwnd); SendMessage(g_hwndTabView, TCM_SETITEMSIZE, 0, MAKELPARAM(150, 0)); SetStatusBarParts(g_hwndStatusBar); hwndHV = g_hwndHexView; mainWnd->hwndMain = hwnd; mainWnd->hwndStatusBar = g_hwndStatusBar; mainWnd->hwndTabView = g_hwndTabView; CreateToolTip(g_hwndHexView); // g_hwndDock[0] = CreateDockWnd(&dock, hwnd, TEXT("Toolbar")); //g_hwndToolbar = InitToolbar(hwnd); //g_hwndSearchBar = CreateSearchBar(hwnd); //g_hwndTypeView = CreateTypeView(hwnd); SetFocus(hwndHV); // tell windows that we can handle drag+drop'd files DragAcceptFiles(hwnd, TRUE); UpdateRecentMenu(GetSubMenu(GetMenu(hwnd), 0)); SetTimer(hwnd, 0xdeadbeef, 1000, 0); return TRUE; case WM_TIMER: if(wParam == 0xdeadbeef) { KillTimer(hwnd, wParam); //FirstTimeOptions(hwnd); } return 0; case WM_DROPFILES: // get the screen coordinates of the drop-location if(DragQueryPoint((HDROP)wParam, &pt)) ClientToScreen(hwnd, &pt); GetWindowRect(hwndHV, &rect); // drop anywhere *except* the hexview, as that does D&D itself if(!PtInRect(&rect, pt)) { HandleDropFiles(hwnd, (HDROP)wParam); } //CreateToolTip(mainWnd->hwndTabView); return 0; case WM_ENABLE: EnableWindow(g_hwndSearch, (BOOL)wParam); EnableWindow(g_hwndGoto, (BOOL)wParam); return 0; case WM_CONTEXTMENU: if((HWND)wParam == DockWnd_GetWindow(hwnd, DWID_TYPEVIEW)) { HMENU hMenu = GetSubMenu(LoadMenu(g_hInstance, MAKEINTRESOURCE(IDR_TYPECONTEXT)), 0); UINT u; MenuCheckMark(hMenu, IDM_TYPEVIEW_HEX, g_fDisplayHex); MenuCheckMark(hMenu, IDM_TYPEVIEW_BIGENDIAN, g_fDisplayBigEndian); u = TrackPopupMenu(hMenu, TPM_RETURNCMD, (short)LOWORD(lParam), (short)HIWORD(lParam), 0, hwnd, 0); SendMessage(DockWnd_GetContents(hwnd, DWID_TYPEVIEW), WM_COMMAND, u, 0); } break; case WM_COMMAND: return HexEdit_OnCommand(hwnd, LOWORD(wParam), HIWORD(wParam), (HWND)lParam); case WM_NOTIFY: hdr = (NMHDR *)lParam; if(hdr->hwndFrom == hwndHV) return HexViewNotifyHandler(mainWnd, hwnd, hdr); else return HexEdit_OnNotify(mainWnd, hwnd, (UINT)wParam, (NMHDR *)lParam); case WM_CLOSE: tci.mask = TCIF_PARAM; for(i = 0; (hwndHV = EnumHexView(hwnd, i)) != NULL; ) { UINT uAnswer = HexFileCloseNotify(hwnd, hwndHV); if(uAnswer == IDCANCEL) { return 0; } else if(uAnswer == IDNO) { SaveHighlights(hwndHV); TabCtrl_DeleteItem(mainWnd->hwndTabView, i); } else { i++; } } // save settings *before* we destroy anything! DockWnd_SaveSettings(hwnd); // shut program down DestroyWindow(hwnd); return 0; case WM_DESTROY: DestroyWindow(hwndHV); // PostQuitMessage(0); return 0; case WM_SETFOCUS: SetFocus(hwndHV); return 0; case WM_SIZE: MainWndSize(mainWnd, LOWORD(lParam), HIWORD(lParam)); UpdateStatusbar(mainWnd->hwndStatusBar); return 0; case WM_INITMENUPOPUP: hMenu = (HMENU)wParam;//GetMenu(hwnd); MenuCheckMark(hMenu, IDM_VIEW_TOOLBAR, DockWnd_IsOpen(hwnd, DWID_TOOLBAR)); MenuCheckMark(hMenu, IDM_TOOLS_TYPEVIEW, DockWnd_IsOpen(hwnd, DWID_TYPEVIEW)); MenuCheckMark(hMenu, IDM_TOOLS_SEARCHBAR, DockWnd_IsOpen(hwnd, DWID_SEARCHBAR)); CheckMenuRadioItem(hMenu, IDM_VIEW_HEX, IDM_VIEW_BIN, IDM_VIEW_HEX + (HexView_GetStyle(hwndHV) & HVS_FORMAT_MASK), MF_BYCOMMAND); { int look[32] = { 0, 0, 1, 0, 2 }; CheckMenuRadioItem(hMenu, IDM_GROUP_BYTE, IDM_GROUP_DWORD, IDM_GROUP_BYTE + look[HexView_GetGrouping(hwndHV)], MF_BYCOMMAND); } { size_w selsize; UINT edmode = HexView_GetEditMode(hwndHV); BOOL cftext = IsClipboardFormatAvailable(CF_TEXT); BOOL canundo = HexView_CanUndo(hwndHV); BOOL canredo = HexView_CanRedo(hwndHV); HexView_GetSelSize(hwndHV, &selsize); //hMenu = GetSubMenu(GetMenu(hwnd), 1); EnableMenuCmdItem(hMenu, IDM_EDIT_UNDO, canundo); EnableMenuCmdItem(hMenu, IDM_EDIT_REDO, canredo); EnableMenuCmdItem(hMenu, IDM_EDIT_CUT, selsize > 0 && edmode == HVMODE_INSERT); EnableMenuCmdItem(hMenu, IDM_EDIT_COPY, selsize > 0); EnableMenuCmdItem(hMenu, IDM_EDIT_COPYAS, selsize > 0); EnableMenuCmdItem(hMenu, IDM_EDIT_PASTE, cftext && edmode != HVMODE_READONLY ); EnableMenuCmdItem(hMenu, IDM_EDIT_PASTESPECIAL, edmode != HVMODE_READONLY ); EnableMenuCmdItem(hMenu, IDM_EDIT_DELETE, selsize > 0 && edmode != HVMODE_READONLY ); EnableMenuCmdItem(hMenu, IDM_EDIT_REVERSE, selsize > 0 && edmode != HVMODE_READONLY ); EnableMenuCmdItem(hMenu, IDM_TOOLS_TRANSFORM, selsize > 0 && edmode != HVMODE_READONLY ); EnableMenuCmdItem(hMenu, IDM_FILE_REVERT, canundo || canredo); } return 0; } return DefWindowProc(hwnd, msg, wParam, lParam); }
// Window callback function (handles window messages) // static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { _GLFWwindow* window = (_GLFWwindow*) GetWindowLongPtrW(hWnd, 0); if (!window) { switch (uMsg) { case WM_NCCREATE: { CREATESTRUCTW* cs = (CREATESTRUCTW*) lParam; SetWindowLongPtrW(hWnd, 0, (LONG_PTR) cs->lpCreateParams); break; } case WM_DEVICECHANGE: { if (wParam == DBT_DEVNODES_CHANGED) { _glfwInputMonitorChange(); return TRUE; } break; } } return DefWindowProcW(hWnd, uMsg, wParam, lParam); } switch (uMsg) { case WM_SETFOCUS: { if (window->cursorMode == GLFW_CURSOR_DISABLED) _glfwPlatformSetCursorMode(window, GLFW_CURSOR_DISABLED); _glfwInputWindowFocus(window, GLFW_TRUE); return 0; } case WM_KILLFOCUS: { if (window->cursorMode == GLFW_CURSOR_DISABLED) _glfwPlatformSetCursorMode(window, GLFW_CURSOR_NORMAL); if (window->monitor && window->autoIconify) _glfwPlatformIconifyWindow(window); _glfwInputWindowFocus(window, GLFW_FALSE); return 0; } case WM_SYSCOMMAND: { switch (wParam & 0xfff0) { case SC_SCREENSAVE: case SC_MONITORPOWER: { if (window->monitor) { // We are running in full screen mode, so disallow // screen saver and screen blanking return 0; } else break; } // User trying to access application menu using ALT? case SC_KEYMENU: return 0; } break; } case WM_CLOSE: { _glfwInputWindowCloseRequest(window); return 0; } case WM_CHAR: case WM_SYSCHAR: case WM_UNICHAR: { const GLFWbool plain = (uMsg != WM_SYSCHAR); if (uMsg == WM_UNICHAR && wParam == UNICODE_NOCHAR) { // WM_UNICHAR is not sent by Windows, but is sent by some // third-party input method engine // Returning TRUE here announces support for this message return TRUE; } _glfwInputChar(window, (unsigned int) wParam, getKeyMods(), plain); return 0; } case WM_KEYDOWN: case WM_SYSKEYDOWN: case WM_KEYUP: case WM_SYSKEYUP: { const int key = translateKey(wParam, lParam); const int scancode = (lParam >> 16) & 0x1ff; const int action = ((lParam >> 31) & 1) ? GLFW_RELEASE : GLFW_PRESS; const int mods = getKeyMods(); if (key == _GLFW_KEY_INVALID) break; if (action == GLFW_RELEASE && wParam == VK_SHIFT) { // Release both Shift keys on Shift up event, as only one event // is sent even if both keys are released _glfwInputKey(window, GLFW_KEY_LEFT_SHIFT, scancode, action, mods); _glfwInputKey(window, GLFW_KEY_RIGHT_SHIFT, scancode, action, mods); } else if (wParam == VK_SNAPSHOT) { // Key down is not reported for the Print Screen key _glfwInputKey(window, key, scancode, GLFW_PRESS, mods); _glfwInputKey(window, key, scancode, GLFW_RELEASE, mods); } else _glfwInputKey(window, key, scancode, action, mods); break; } case WM_LBUTTONDOWN: case WM_RBUTTONDOWN: case WM_MBUTTONDOWN: case WM_XBUTTONDOWN: case WM_LBUTTONUP: case WM_RBUTTONUP: case WM_MBUTTONUP: case WM_XBUTTONUP: { int button, action; if (uMsg == WM_LBUTTONDOWN || uMsg == WM_LBUTTONUP) button = GLFW_MOUSE_BUTTON_LEFT; else if (uMsg == WM_RBUTTONDOWN || uMsg == WM_RBUTTONUP) button = GLFW_MOUSE_BUTTON_RIGHT; else if (uMsg == WM_MBUTTONDOWN || uMsg == WM_MBUTTONUP) button = GLFW_MOUSE_BUTTON_MIDDLE; else if (GET_XBUTTON_WPARAM(wParam) == XBUTTON1) button = GLFW_MOUSE_BUTTON_4; else button = GLFW_MOUSE_BUTTON_5; if (uMsg == WM_LBUTTONDOWN || uMsg == WM_RBUTTONDOWN || uMsg == WM_MBUTTONDOWN || uMsg == WM_XBUTTONDOWN) { action = GLFW_PRESS; SetCapture(hWnd); } else { action = GLFW_RELEASE; ReleaseCapture(); } _glfwInputMouseClick(window, button, action, getKeyMods()); if (uMsg == WM_XBUTTONDOWN || uMsg == WM_XBUTTONUP) return TRUE; return 0; } case WM_MOUSEMOVE: { const int x = GET_X_LPARAM(lParam); const int y = GET_Y_LPARAM(lParam); if (window->cursorMode == GLFW_CURSOR_DISABLED) { if (_glfw.cursorWindow != window) break; _glfwInputCursorMotion(window, x - window->win32.cursorPosX, y - window->win32.cursorPosY); } else _glfwInputCursorMotion(window, x, y); window->win32.cursorPosX = x; window->win32.cursorPosY = y; if (!window->win32.cursorTracked) { TRACKMOUSEEVENT tme; ZeroMemory(&tme, sizeof(tme)); tme.cbSize = sizeof(tme); tme.dwFlags = TME_LEAVE; tme.hwndTrack = window->win32.handle; TrackMouseEvent(&tme); window->win32.cursorTracked = GLFW_TRUE; _glfwInputCursorEnter(window, GLFW_TRUE); } return 0; } case WM_MOUSELEAVE: { window->win32.cursorTracked = GLFW_FALSE; _glfwInputCursorEnter(window, GLFW_FALSE); return 0; } case WM_MOUSEWHEEL: { _glfwInputScroll(window, 0.0, (SHORT) HIWORD(wParam) / (double) WHEEL_DELTA); return 0; } case WM_MOUSEHWHEEL: { // This message is only sent on Windows Vista and later // NOTE: The X-axis is inverted for consistency with OS X and X11. _glfwInputScroll(window, -((SHORT) HIWORD(wParam) / (double) WHEEL_DELTA), 0.0); return 0; } case WM_SIZE: { if (_glfw.cursorWindow == window) { if (window->cursorMode == GLFW_CURSOR_DISABLED) updateClipRect(window); } if (!window->win32.iconified && wParam == SIZE_MINIMIZED) { window->win32.iconified = GLFW_TRUE; if (window->monitor) leaveFullscreenMode(window); _glfwInputWindowIconify(window, GLFW_TRUE); } else if (window->win32.iconified && (wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED)) { window->win32.iconified = GLFW_FALSE; if (window->monitor) enterFullscreenMode(window); _glfwInputWindowIconify(window, GLFW_FALSE); } _glfwInputFramebufferSize(window, LOWORD(lParam), HIWORD(lParam)); _glfwInputWindowSize(window, LOWORD(lParam), HIWORD(lParam)); return 0; } case WM_MOVE: { if (_glfw.cursorWindow == window) { if (window->cursorMode == GLFW_CURSOR_DISABLED) updateClipRect(window); } // NOTE: This cannot use LOWORD/HIWORD recommended by MSDN, as // those macros do not handle negative window positions correctly _glfwInputWindowPos(window, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); return 0; } case WM_SIZING: { if (window->win32.numer == GLFW_DONT_CARE || window->win32.denom == GLFW_DONT_CARE) { break; } applyAspectRatio(window, (int) wParam, (RECT*) lParam); return TRUE; } case WM_GETMINMAXINFO: { int xoff, yoff; MINMAXINFO* mmi = (MINMAXINFO*) lParam; getFullWindowSize(getWindowStyle(window), getWindowExStyle(window), 0, 0, &xoff, &yoff); if (window->win32.minwidth != GLFW_DONT_CARE && window->win32.minheight != GLFW_DONT_CARE) { mmi->ptMinTrackSize.x = window->win32.minwidth + xoff; mmi->ptMinTrackSize.y = window->win32.minheight + yoff; } if (window->win32.maxwidth != GLFW_DONT_CARE && window->win32.maxheight != GLFW_DONT_CARE) { mmi->ptMaxTrackSize.x = window->win32.maxwidth + xoff; mmi->ptMaxTrackSize.y = window->win32.maxheight + yoff; } return 0; } case WM_PAINT: { _glfwInputWindowDamage(window); break; } case WM_ERASEBKGND: { return TRUE; } case WM_SETCURSOR: { if (_glfw.cursorWindow == window && LOWORD(lParam) == HTCLIENT) { if (window->cursorMode == GLFW_CURSOR_HIDDEN || window->cursorMode == GLFW_CURSOR_DISABLED) { SetCursor(NULL); return TRUE; } else if (window->cursor) { SetCursor(window->cursor->win32.handle); return TRUE; } } break; } case WM_DPICHANGED: { RECT* rect = (RECT*) lParam; SetWindowPos(window->win32.handle, HWND_TOP, rect->left, rect->top, rect->right - rect->left, rect->bottom - rect->top, SWP_NOACTIVATE | SWP_NOZORDER); break; } case WM_DROPFILES: { HDROP drop = (HDROP) wParam; POINT pt; int i; const int count = DragQueryFileW(drop, 0xffffffff, NULL, 0); char** paths = calloc(count, sizeof(char*)); // Move the mouse to the position of the drop DragQueryPoint(drop, &pt); _glfwInputCursorMotion(window, pt.x, pt.y); for (i = 0; i < count; i++) { const UINT length = DragQueryFileW(drop, i, NULL, 0); WCHAR* buffer = calloc(length + 1, sizeof(WCHAR)); DragQueryFileW(drop, i, buffer, length + 1); paths[i] = _glfwCreateUTF8FromWideStringWin32(buffer); free(buffer); } _glfwInputDrop(window, count, (const char**) paths); for (i = 0; i < count; i++) free(paths[i]); free(paths); DragFinish(drop); return 0; } } return DefWindowProcW(hWnd, uMsg, wParam, lParam); }