static LRESULT WINAPI MainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch(uMsg) { case WM_CREATE: { TEXTMETRICW tm; HDC hDC = GetDC(hWnd); /* * Note that the method with GetObjectW just returns * the original parameters with which the font was created. */ if (GetTextMetricsW(hDC, &tm)) { Globals.CharWidth = tm.tmMaxCharWidth; // tm.tmAveCharWidth; Globals.CharHeight = tm.tmHeight + tm.tmExternalLeading; } ReleaseDC(hWnd, hDC); Globals.hMenu = GetMenu(hWnd); Globals.hWndNext = SetClipboardViewer(hWnd); // For now, the Help dialog item is disabled because of lacking of HTML support EnableMenuItem(Globals.hMenu, CMD_HELP, MF_BYCOMMAND | MF_GRAYED); UpdateLinesToScroll(&Scrollstate); UpdateDisplayMenu(); SetDisplayFormat(0); DragAcceptFiles(hWnd, TRUE); break; } case WM_CLOSE: { DestroyWindow(hWnd); break; } case WM_DESTROY: { ChangeClipboardChain(hWnd, Globals.hWndNext); if (Globals.uDisplayFormat == CF_OWNERDISPLAY) { HGLOBAL hglb; PRECT prc; hglb = GlobalAlloc(GMEM_MOVEABLE, sizeof(*prc)); if (hglb) { prc = GlobalLock(hglb); SetRectEmpty(prc); GlobalUnlock(hglb); SendClipboardOwnerMessage(TRUE, WM_SIZECLIPBOARD, (WPARAM)hWnd, (LPARAM)hglb); GlobalFree(hglb); } } PostQuitMessage(0); break; } case WM_PAINT: { OnPaint(hWnd, wParam, lParam); break; } case WM_KEYDOWN: { OnKeyScroll(hWnd, wParam, lParam, &Scrollstate); break; } case WM_MOUSEWHEEL: case WM_MOUSEHWHEEL: { OnMouseScroll(hWnd, uMsg, wParam, lParam, &Scrollstate); break; } case WM_HSCROLL: { // NOTE: Windows uses an offset of 16 pixels OnScroll(hWnd, SB_HORZ, wParam, 5, &Scrollstate); break; } case WM_VSCROLL: { // NOTE: Windows uses an offset of 16 pixels OnScroll(hWnd, SB_VERT, wParam, 5, &Scrollstate); break; } case WM_SIZE: { RECT rc; if (Globals.uDisplayFormat == CF_OWNERDISPLAY) { HGLOBAL hglb; PRECT prc; hglb = GlobalAlloc(GMEM_MOVEABLE, sizeof(*prc)); if (hglb) { prc = GlobalLock(hglb); if (wParam == SIZE_MINIMIZED) SetRectEmpty(prc); else GetClientRect(hWnd, prc); GlobalUnlock(hglb); SendClipboardOwnerMessage(TRUE, WM_SIZECLIPBOARD, (WPARAM)hWnd, (LPARAM)hglb); GlobalFree(hglb); } break; } GetClipboardDataDimensions(Globals.uDisplayFormat, &rc); UpdateWindowScrollState(hWnd, rc.right, rc.bottom, &Scrollstate); // NOTE: There still are little problems drawing // the background when displaying clipboard text. if (!IsClipboardFormatSupported(Globals.uDisplayFormat) || Globals.uDisplayFormat == CF_DSPTEXT || Globals.uDisplayFormat == CF_TEXT || Globals.uDisplayFormat == CF_OEMTEXT || Globals.uDisplayFormat == CF_UNICODETEXT) { InvalidateRect(Globals.hMainWnd, NULL, TRUE); } else { InvalidateRect(Globals.hMainWnd, NULL, FALSE); } break; } case WM_CHANGECBCHAIN: { /* Transmit through the clipboard viewer chain */ if ((HWND)wParam == Globals.hWndNext) { Globals.hWndNext = (HWND)lParam; } else if (Globals.hWndNext != NULL) { SendMessageW(Globals.hWndNext, uMsg, wParam, lParam); } break; } case WM_DESTROYCLIPBOARD: break; case WM_RENDERALLFORMATS: { /* * When the user has cleared the clipboard via the DELETE command, * we (clipboard viewer) become the clipboard owner. When we are * subsequently closed, this message is then sent to us so that * we get a chance to render everything we can. Since we don't have * anything to render, just empty the clipboard. */ DeleteClipboardContent(); break; } case WM_RENDERFORMAT: // TODO! break; case WM_DRAWCLIPBOARD: { UpdateDisplayMenu(); SetDisplayFormat(0); /* Pass the message to the next window in clipboard viewer chain */ SendMessageW(Globals.hWndNext, uMsg, wParam, lParam); break; } case WM_COMMAND: { if ((LOWORD(wParam) > CMD_AUTOMATIC)) { SetDisplayFormat(LOWORD(wParam) - CMD_AUTOMATIC); } else { OnCommand(hWnd, uMsg, wParam, lParam); } break; } case WM_INITMENUPOPUP: { InitMenuPopup((HMENU)wParam, lParam); break; } case WM_DROPFILES: { LoadClipboardFromDrop((HDROP)wParam); break; } case WM_PALETTECHANGED: { /* Ignore if this comes from ourselves */ if ((HWND)wParam == hWnd) break; /* Fall back to WM_QUERYNEWPALETTE */ } case WM_QUERYNEWPALETTE: { BOOL Success; HDC hDC; if (!OpenClipboard(Globals.hMainWnd)) return FALSE; hDC = GetDC(hWnd); if (!hDC) { CloseClipboard(); return FALSE; } Success = RealizeClipboardPalette(hDC); ReleaseDC(hWnd, hDC); CloseClipboard(); if (Success) { InvalidateRect(hWnd, NULL, TRUE); UpdateWindow(hWnd); return TRUE; } return FALSE; } case WM_SYSCOLORCHANGE: { SetDisplayFormat(Globals.uDisplayFormat); break; } case WM_SETTINGCHANGE: { if (wParam == SPI_SETWHEELSCROLLLINES) { UpdateLinesToScroll(&Scrollstate); } break; } default: { return DefWindowProc(hWnd, uMsg, wParam, lParam); } } return 0; }
bool CUIWindow::OnMouse(float x, float y, EUIMessages mouse_action) { Frect wndRect = GetWndRect(); cursor_pos.x = x; cursor_pos.y = y; if( WINDOW_LBUTTON_DOWN == mouse_action ) { static u32 _last_db_click_frame = 0; u32 dwCurTime = Device.dwTimeContinual; if( (_last_db_click_frame!=Device.dwFrame) && (dwCurTime-m_dwLastClickTime < DOUBLE_CLICK_TIME) ) { mouse_action = WINDOW_LBUTTON_DB_CLICK; _last_db_click_frame = Device.dwFrame; } m_dwLastClickTime = dwCurTime; } if(GetParent()== NULL) { if(!wndRect.in(cursor_pos)) return false; //получить координаты относительно окна cursor_pos.x -= wndRect.left; cursor_pos.y -= wndRect.top; } //если есть дочернее окно,захватившее мышь, то //сообщение направляем ему сразу if(m_pMouseCapturer) { m_pMouseCapturer->OnMouse(cursor_pos.x - m_pMouseCapturer->GetWndRect().left, cursor_pos.y - m_pMouseCapturer->GetWndRect().top, mouse_action); return true; } // handle any action switch (mouse_action){ case WINDOW_MOUSE_MOVE: OnMouseMove(); break; case WINDOW_MOUSE_WHEEL_DOWN: OnMouseScroll(WINDOW_MOUSE_WHEEL_DOWN); break; case WINDOW_MOUSE_WHEEL_UP: OnMouseScroll(WINDOW_MOUSE_WHEEL_UP); break; case WINDOW_LBUTTON_DOWN: if(OnMouseDown(MOUSE_1)) return true; break; case WINDOW_RBUTTON_DOWN: if(OnMouseDown(MOUSE_2)) return true; break; case WINDOW_CBUTTON_DOWN: if(OnMouseDown(MOUSE_3)) return true; break; case WINDOW_LBUTTON_DB_CLICK: if (OnDbClick()) return true; break; default: break; } //Проверка на попадание мыши в окно, //происходит в обратном порядке, чем рисование окон //(последние в списке имеют высший приоритет) WINDOW_LIST::reverse_iterator it = m_ChildWndList.rbegin(); for(; it!=m_ChildWndList.rend(); ++it) { CUIWindow* w = (*it); Frect wndRect = w->GetWndRect(); if (wndRect.in(cursor_pos) ) { if(w->IsEnabled()) { if( w->OnMouse(cursor_pos.x -w->GetWndRect().left, cursor_pos.y -w->GetWndRect().top, mouse_action))return true; } } else if (w->IsEnabled() && w->CursorOverWindow()) { if( w->OnMouse(cursor_pos.x -w->GetWndRect().left, cursor_pos.y -w->GetWndRect().top, mouse_action))return true; } } return false; }
UINT NervWindowHandler::OnMouseWheel(WPARAM wParam, LPARAM lParam){ NervMouseScrollEvent event{int(wParam), int(lParam)}; OnMouseScroll(&event); return 0; }