static inline bool findPlatformWindowHelper(const POINT &screenPoint, unsigned cwexFlags, const QWindowsContext *context, HWND *hwnd, QWindowsWindow **result) { POINT point = screenPoint; ScreenToClient(*hwnd, &point); // Returns parent if inside & none matched. #ifndef Q_OS_WINCE const HWND child = ChildWindowFromPointEx(*hwnd, point, cwexFlags); #else // Under Windows CE we don't use ChildWindowFromPointEx as it's not available // and ChildWindowFromPoint does not work properly. Q_UNUSED(cwexFlags) const HWND child = WindowFromPoint(point); #endif if (!child || child == *hwnd) return false; if (QWindowsWindow *window = context->findPlatformWindow(child)) { *result = window; *hwnd = child; #ifndef Q_OS_WINCE return true; #else // WindowFromPoint does not return same handle in two sequential calls, which leads // to an endless loop, but calling WindowFromPoint once is good enough. return false; #endif } #ifndef Q_OS_WINCE // Does not have WS_EX_TRANSPARENT . // QTBUG-40555: despite CWP_SKIPINVISIBLE, it is possible to hit on invisible // full screen windows of other applications that have WS_EX_TRANSPARENT set // (for example created by screen sharing applications). In that case, try to // find a Qt window by searching again with CWP_SKIPTRANSPARENT. // Note that Qt 5 uses WS_EX_TRANSPARENT for Qt::WindowTransparentForInput // as well. if (!(cwexFlags & CWP_SKIPTRANSPARENT) && (GetWindowLongPtr(child, GWL_EXSTYLE) & WS_EX_TRANSPARENT)) { const HWND nonTransparentChild = ChildWindowFromPointEx(*hwnd, point, cwexFlags | CWP_SKIPTRANSPARENT); if (QWindowsWindow *nonTransparentWindow = context->findPlatformWindow(nonTransparentChild)) { *result = nonTransparentWindow; *hwnd = nonTransparentChild; return true; } } #endif // !Q_OS_WINCE *hwnd = child; return true; }
static HWND find_drop_window( HWND hQueryWnd, LPPOINT lpPt ) { RECT tempRect; if (!IsWindowEnabled(hQueryWnd)) return 0; GetWindowRect(hQueryWnd, &tempRect); if(!PtInRect(&tempRect, *lpPt)) return 0; if (!IsIconic( hQueryWnd )) { POINT pt = *lpPt; ScreenToClient( hQueryWnd, &pt ); GetClientRect( hQueryWnd, &tempRect ); if (PtInRect( &tempRect, pt)) { HWND ret = ChildWindowFromPointEx( hQueryWnd, pt, CWP_SKIPINVISIBLE|CWP_SKIPDISABLED ); if (ret && ret != hQueryWnd) { ret = find_drop_window( ret, lpPt ); if (ret) return ret; } } } if(!(GetWindowLongA( hQueryWnd, GWL_EXSTYLE ) & WS_EX_ACCEPTFILES)) return 0; ScreenToClient(hQueryWnd, lpPt); return hQueryWnd; }
static HRESULT WINAPI Client_accHitTest(IAccessible *iface, LONG xLeft, LONG yTop, VARIANT *pvarID) { Client *This = impl_from_Client(iface); HWND child; POINT pt; TRACE("(%p)->(%d %d %p)\n", This, xLeft, yTop, pvarID); V_VT(pvarID) = VT_I4; V_I4(pvarID) = 0; pt.x = xLeft; pt.y = yTop; if(!IsWindowVisible(This->hwnd) || !ScreenToClient(This->hwnd, &pt)) return S_OK; child = ChildWindowFromPointEx(This->hwnd, pt, CWP_SKIPINVISIBLE); if(!child || child==This->hwnd) return S_OK; V_VT(pvarID) = VT_DISPATCH; return AccessibleObjectFromWindow(child, OBJID_WINDOW, &IID_IDispatch, (void**)&V_DISPATCH(pvarID)); }
static void CALLBACK NoMouseMoveForDelayTimerProc(HWND hwnd, UINT, UINT_PTR idTimer, DWORD) { POINT pt; HWND hwndCtl; struct FindChildAtPointData fcap; KillTimer(hwnd, idTimer); if (idMouseMoveTimer != idTimer) return; idMouseMoveTimer = 0; if (!settingAutoTipDelay || !IsWindow(hwndMouseMoveDlg)) return; ZeroMemory(&fcap, sizeof(fcap)); if (!GetCursorPos(&pt)) return; // ChildWindowFromPoint() messes up with group boxes fcap.hwnd = NULL; fcap.pt = pt; EnumChildWindows(hwndMouseMoveDlg, FindChildAtPointEnumProc, (LPARAM)&fcap); hwndCtl = fcap.hwnd; if (hwndCtl == NULL) { ScreenToClient(hwndMouseMoveDlg, &pt); hwndCtl = ChildWindowFromPointEx(hwndMouseMoveDlg, pt, CWP_SKIPINVISIBLE); if (hwndCtl == NULL) return; } LONG_PTR flags = (LONG_PTR)GetProp(hwndCtl, PROP_CONTEXTSTATE); if (flags&PROPF_AUTOTIPDISABLED) return; flags = SendMessage(hwndCtl, WM_GETDLGCODE, (WPARAM)VK_RETURN, (LPARAM)NULL); if (flags&DLGC_HASSETSEL || flags&DLGC_WANTALLKEYS) return; // autotips on edits are annoying CURSORINFO ci; BOOL(WINAPI *pfnGetCursorInfo)(CURSORINFO*); ci.cbSize = sizeof(ci); *(FARPROC*)&pfnGetCursorInfo = GetProcAddress(GetModuleHandleA("USER32"), "GetCursorInfo"); // if(pfnGetCursorInfo && IsWinVer2000Plus()) // call not safe for WinNT4 if (pfnGetCursorInfo(&ci) && !(ci.flags&CURSOR_SHOWING)) return; if (IsRealChild(hwndMouseMoveDlg, hwndCtl) && hwndHelpDlg == NULL) { hwndHelpDlg = CreateDialog(hInst, MAKEINTRESOURCE(IDD_HELP), NULL, HelpDlgProc); if (hwndHelpDlg == NULL) return; openedAutoTip = 1; PostMessage(hwndHelpDlg, M_CHANGEHELPCONTROL, 0, (LPARAM)hwndCtl); } }
QWindowsWindow *QWindowsContext::findPlatformWindowAt(HWND parent, const QPoint &screenPointIn, unsigned cwex_flags) const { QWindowsWindow *result = 0; const POINT screenPoint = { screenPointIn.x(), screenPointIn.y() }; while (true) { POINT point = screenPoint; ScreenToClient(parent, &point); // Returns parent if inside & none matched. const HWND child = ChildWindowFromPointEx(parent, point, cwex_flags); if (child && child != parent) { if (QWindowsWindow *window = findPlatformWindow(child)) result = window; parent = child; } else { break; } } return result; }
static GdkWindow * gdk_device_win32_window_at_position (GdkDevice *device, gdouble *win_x, gdouble *win_y, GdkModifierType *mask, gboolean get_toplevel) { GdkWindow *window = NULL; POINT screen_pt, client_pt; HWND hwnd, hwndc; RECT rect; GetCursorPos (&screen_pt); if (get_toplevel) { /* Only consider visible children of the desktop to avoid the various * non-visible windows you often find on a running Windows box. These * might overlap our windows and cause our walk to fail. As we assume * WindowFromPoint() can find our windows, we follow similar logic * here, and ignore invisible and disabled windows. */ hwnd = GetDesktopWindow (); do { window = gdk_win32_handle_table_lookup (hwnd); if (window != NULL && GDK_WINDOW_TYPE (window) != GDK_WINDOW_ROOT && GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN) break; screen_to_client (hwnd, screen_pt, &client_pt); hwndc = ChildWindowFromPointEx (hwnd, client_pt, CWP_SKIPDISABLED | CWP_SKIPINVISIBLE); /* Verify that we're really inside the client area of the window */ if (hwndc != hwnd) { GetClientRect (hwndc, &rect); screen_to_client (hwndc, screen_pt, &client_pt); if (!PtInRect (&rect, client_pt)) hwndc = hwnd; } } while (hwndc != hwnd && (hwnd = hwndc, 1)); } else { hwnd = WindowFromPoint (screen_pt); /* Verify that we're really inside the client area of the window */ GetClientRect (hwnd, &rect); screen_to_client (hwnd, screen_pt, &client_pt); if (!PtInRect (&rect, client_pt)) hwnd = NULL; /* If we didn't hit any window at that point, return the desktop */ if (hwnd == NULL) { if (win_x) *win_x = screen_pt.x + _gdk_offset_x; if (win_y) *win_y = screen_pt.y + _gdk_offset_y; return _gdk_root; } window = gdk_win32_handle_table_lookup (hwnd); } if (window && (win_x || win_y)) { if (win_x) *win_x = client_pt.x; if (win_y) *win_y = client_pt.y; } return window; }
static LRESULT CALLBACK DialogBoxSubclassProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { int i; EnterCriticalSection(&csDlgBoxSubclass); for (i = 0; i<dlgBoxSubclassCount; i++) if (dlgBoxSubclass[i].hwndDlg == hwndDlg) break; if (i == dlgBoxSubclassCount) { LeaveCriticalSection(&csDlgBoxSubclass); return 0; } WNDPROC pfnWndProc = dlgBoxSubclass[i].pfnOldWndProc; DWORD flags = dlgBoxSubclass[i].flags; if (msg == WM_NCDESTROY) { struct DlgBoxSubclassData *buf; MoveMemory(dlgBoxSubclass + i, dlgBoxSubclass + i + 1, sizeof(struct DlgBoxSubclassData)*(dlgBoxSubclassCount - i - 1)); dlgBoxSubclassCount--; buf = (struct DlgBoxSubclassData*)mir_realloc(dlgBoxSubclass, sizeof(struct DlgBoxSubclassData)*dlgBoxSubclassCount); if (buf != NULL) dlgBoxSubclass = buf; else if (!dlgBoxSubclassCount) dlgBoxSubclass = NULL; } LeaveCriticalSection(&csDlgBoxSubclass); switch (msg) { case WM_INITMENUPOPUP: if (flags&DBSDF_MINIMIZABLE || flags&DBSDF_MAXIMIZABLE) { HMENU hMenu = GetSystemMenu(hwndDlg, FALSE); if ((HMENU)wParam != hMenu) break; int isMin = IsIconic(hwndDlg); int isMax = IsZoomed(hwndDlg); EnableMenuItem(hMenu, SC_RESTORE, MF_BYCOMMAND | (isMin || isMax) ? MF_ENABLED : MF_GRAYED); EnableMenuItem(hMenu, SC_MINIMIZE, MF_BYCOMMAND | (flags&DBSDF_MINIMIZABLE && !isMin) ? MF_ENABLED : MF_GRAYED); EnableMenuItem(hMenu, SC_MAXIMIZE, MF_BYCOMMAND | (flags&DBSDF_MAXIMIZABLE && !isMax) ? MF_ENABLED : MF_GRAYED); EnableMenuItem(hMenu, SC_SIZE, MF_BYCOMMAND | (GetWindowLongPtr(hwndDlg, GWL_STYLE)&WS_THICKFRAME && !isMin && !isMax) ? MF_ENABLED : MF_GRAYED); } break; case WM_MOUSEMOVE: // TrackMouseEvent() would disturb too much if (!settingAutoTipDelay) break; if (cursorPos == lParam) break; cursorPos = lParam; case WM_LBUTTONDOWN: case WM_LBUTTONUP: case WM_MOUSEWHEEL: if (!settingAutoTipDelay) break; if (msg != WM_MOUSEMOVE && !idMouseMoveTimer) break; if (openedAutoTip && IsWindow(hwndHelpDlg)) DestroyWindow(hwndHelpDlg); openedAutoTip = 0; hwndMouseMoveDlg = hwndDlg; if (hwndHelpDlg == NULL) idMouseMoveTimer = SetTimer(NULL, idMouseMoveTimer, settingAutoTipDelay, NoMouseMoveForDelayTimerProc); break; case WM_CAPTURECHANGED: if ((HWND)lParam == hwndDlg) break; case WM_SHOWWINDOW: case WM_WINDOWPOSCHANGING: case WM_MOVING: case WM_SIZING: case WM_CANCELMODE: case WM_CHILDACTIVATE: case WM_MOUSEACTIVATE: case WM_ACTIVATEAPP: case WM_ACTIVATE: if (idMouseMoveTimer) KillTimer(NULL, idMouseMoveTimer); idMouseMoveTimer = 0; break; case WM_SYSCOMMAND: if ((UINT)wParam == SC_CONTEXTHELP_DIALOG) { // alt. "What's this dialog?" if (idMouseMoveTimer) KillTimer(NULL, idMouseMoveTimer); idMouseMoveTimer = 0; if (hwndHelpDlg == NULL) { hwndHelpDlg = CreateDialog(hInst, MAKEINTRESOURCE(IDD_HELP), NULL, HelpDlgProc); if (hwndHelpDlg == NULL) break; } SendMessage(hwndHelpDlg, M_CHANGEHELPCONTROL, 0, (LPARAM)hwndDlg); return 0; } break; case WM_CONTEXTMENU: { POINT pt; struct FindChildAtPointData fcap; // workaround for badly coded plugins that do display a context menu // and pass the message to DefWindowProc afterwards (doing a "break;"). if (GetTickCount() - GetMessageTime()>10) return 0; if (idMouseMoveTimer) KillTimer(NULL, idMouseMoveTimer); idMouseMoveTimer = 0; ZeroMemory(&fcap, sizeof(fcap)); POINTSTOPOINT(pt, MAKEPOINTS(lParam)); // ChildWindowFromPoint() messes up with group boxes fcap.hwnd = NULL; fcap.pt = pt; EnumChildWindows(hwndDlg, FindChildAtPointEnumProc, (LPARAM)&fcap); HWND hwndCtl = fcap.hwnd; if (hwndCtl == NULL) { ScreenToClient(hwndDlg, &pt); hwndCtl = ChildWindowFromPointEx(hwndDlg, pt, CWP_SKIPINVISIBLE); if (hwndCtl == NULL) break; POINTSTOPOINT(pt, MAKEPOINTS(lParam)); } { LONG_PTR flags = (LONG_PTR)GetProp(hwndCtl, PROP_CONTEXTSTATE); if (flags&PROPF_MENUDISABLED) break; else if (!(flags&PROPF_MENUFORCED)) { int type = GetControlType(hwndCtl); // showing a context menu on these looks silly (multi components) if (type == CTLTYPE_TOOLBAR || type == CTLTYPE_LISTVIEW || type == CTLTYPE_TREEVIEW || type == CTLTYPE_STATUSBAR || type == CTLTYPE_CLC) break; } } if (IsRealChild(hwndDlg, hwndCtl)) { HMENU hMenu = CreatePopupMenu(); AppendMenu(hMenu, MF_STRING, SC_CONTEXTHELP, (hwndCtl == hwndDlg) ? TranslateT("&What's this dialog?") : TranslateT("&What's this?")); if (TrackPopupMenuEx(hMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_HORPOSANIMATION | TPM_VERPOSANIMATION | TPM_RIGHTBUTTON | TPM_RETURNCMD | TPM_NONOTIFY, pt.x, pt.y, hwndDlg, NULL)) { if (hwndHelpDlg == NULL) { hwndHelpDlg = CreateDialog(hInst, MAKEINTRESOURCE(IDD_HELP), NULL, HelpDlgProc); if (hwndHelpDlg == NULL) { DestroyMenu(hMenu); break; } } SendMessage(hwndHelpDlg, M_CHANGEHELPCONTROL, 0, (LPARAM)hwndCtl); } DestroyMenu(hMenu); } return 0; } case WM_HELP: { HELPINFO *hi = (HELPINFO*)lParam; if (hi->iContextType != HELPINFO_WINDOW) break; // fix for SHBrowseForFolder() dialog, which sends unhandled help to parent if (!IsRealChild(hwndDlg, (HWND)hi->hItemHandle)) break; if (idMouseMoveTimer) KillTimer(NULL, idMouseMoveTimer); idMouseMoveTimer = 0; if (!IsWindow(hwndHelpDlg)) { hwndHelpDlg = CreateDialog(hInst, MAKEINTRESOURCE(IDD_HELP), NULL, HelpDlgProc); if (hwndHelpDlg == NULL) break; } SendMessage(hwndHelpDlg, M_CHANGEHELPCONTROL, 0, (LPARAM)hi->hItemHandle); // we need to eat the next WM_LBUTTONDOWN (if invoked by mouse) if (GetKeyState(GetSystemMetrics(SM_SWAPBUTTON) ? VK_RBUTTON : VK_LBUTTON) & 0x8000 && hEatNextMouseHook == NULL) hEatNextMouseHook = SetWindowsHookEx(WH_MOUSE, EatNextMouseButtonUpHookProc, NULL, GetCurrentThreadId()); return TRUE; } case WM_NCDESTROY: if (idMouseMoveTimer) KillTimer(NULL, idMouseMoveTimer); idMouseMoveTimer = 0; EnumChildWindows(hwndDlg, RemovePropForAllChildsEnumProc, (LPARAM)PROP_CONTEXTSTATE); { TCHAR text[64]; mir_sntprintf(text, _countof(text), _T("unhooked window 0x%X for context help\n"), hwndDlg); OutputDebugString(text); } SetWindowLongPtr(hwndDlg, GWLP_WNDPROC, (LONG_PTR)pfnWndProc); break; } return CallWindowProc(pfnWndProc, hwndDlg, msg, wParam, lParam); }
static LRESULT WINAPI EditIconHintProc(HWND hEditCtrl, UINT Msg, WPARAM wParam, LPARAM lParam) { LRESULT lRc = 0; CEIconHintInfo hi = {}; CEIconDrawHandles dh = {}; bool bKnown = gpIconHints->Get(hEditCtrl, &hi, (Msg == WM_DESTROY)); switch (Msg) { case WM_PAINT: lRc = EditIconHintPaint(hEditCtrl, &hi); goto wrap; case WM_ERASEBKGND: break; case WM_LBUTTONDOWN: case WM_LBUTTONUP: case WM_LBUTTONDBLCLK: case WM_RBUTTONDOWN: case WM_RBUTTONUP: case WM_RBUTTONDBLCLK: case WM_SETCURSOR: if (gpIconHandles->Get(hi.iRes, &dh) && dh.pIcon) { // Cursor over icon? if (EditIconHintOverIcon(hEditCtrl, &hi, (Msg==WM_SETCURSOR)?NULL:&lParam)) { switch (Msg) { case WM_SETCURSOR: SetCursor(LoadCursor(NULL, IDC_ARROW)); lRc = TRUE; break; default: if ((Msg == WM_LBUTTONDOWN || Msg == WM_LBUTTONDBLCLK) && (GetWindowTextLength(hEditCtrl) > 0)) { SendMessage(GetParent(hEditCtrl), hi.nSearchMsg, GetWindowLongPtr(hEditCtrl, GWLP_ID), (LPARAM)hEditCtrl); } } goto wrap; } else if (Msg != WM_SETCURSOR) { // Redraw search icon SetTimer(hEditCtrl, SEARCH_CTRL_REFRID, SEARCH_CTRL_REFR, NULL); } } break; case WM_MOUSEWHEEL: { POINT ptCur = {}; GetCursorPos(&ptCur); HWND hPrevParent = NULL; HWND hParent = hi.hRootDlg; while (hParent) { MapWindowPoints(hPrevParent, hParent, &ptCur, 1); HWND hCtrlOver = ChildWindowFromPointEx(hParent, ptCur, CWP_SKIPDISABLED|CWP_SKIPINVISIBLE|CWP_SKIPTRANSPARENT); if (!hCtrlOver || (hParent == hCtrlOver)) break; wchar_t szClass[64] = L""; GetClassName(hCtrlOver, szClass, countof(szClass)); if (lstrcmp(szClass, L"#32770") == 0) { HWND hSubItem = NULL; EnumChildWindows(hCtrlOver, EditIconHint_FindScrollCtrl, (LPARAM)&hSubItem); hCtrlOver = hSubItem; } if (hCtrlOver) SendMessage(hCtrlOver, Msg, wParam, lParam); break; } } break; case WM_TIMER: switch ((DWORD)wParam) { case SEARCH_CTRL_TIMERID: { int iLen = GetWindowTextLength(hEditCtrl); KillTimer(hEditCtrl, SEARCH_CTRL_TIMERID); if (iLen > 0) { SendMessage(GetParent(hEditCtrl), hi.nSearchMsg, GetWindowLongPtr(hEditCtrl, GWLP_ID), (LPARAM)hEditCtrl); } goto wrap; } break; case SEARCH_CTRL_REFRID: { KillTimer(hEditCtrl, SEARCH_CTRL_REFRID); EditIconHintPaint(hEditCtrl, &hi, 0); goto wrap; } break; } break; // WM_TIMER case WM_SETFOCUS: case WM_KILLFOCUS: if (hi.nDefBtnID) { DWORD dwStyle; HWND hDefBtn = GetDlgItem(hi.hRootDlg, hi.nDefBtnID); if (Msg == WM_SETFOCUS) { dwStyle = GetWindowLong(hDefBtn, GWL_STYLE); SetWindowLong(hDefBtn, GWL_STYLE, dwStyle & ~BS_DEFPUSHBUTTON); } else { dwStyle = GetWindowLong(hDefBtn, GWL_STYLE); SetWindowLong(hDefBtn, GWL_STYLE, dwStyle | BS_DEFPUSHBUTTON); } ::InvalidateRect(hDefBtn, NULL, FALSE); } break; case WM_KEYDOWN: case WM_KEYUP: case WM_CHAR: if (wParam == VK_RETURN) { if (Msg == WM_KEYUP) { PostMessage(hEditCtrl, WM_TIMER, SEARCH_CTRL_TIMERID, 0); } goto wrap; } //else if (hi.lpPrevWndFunc) //{ // // Try to fix ugly icon flickering? // lRc = CallWindowProc(hi.lpPrevWndFunc, hEditCtrl, Msg, wParam, lParam); // KillTimer(hEditCtrl, SEARCH_CTRL_REFRID); // EditIconHintPaint(hEditCtrl, &hi, 0); // goto wrap; //} break; } // Not handled, default window procedure if (hi.lpPrevWndFunc) lRc = CallWindowProc(hi.lpPrevWndFunc, hEditCtrl, Msg, wParam, lParam); else lRc = DefWindowProc(hEditCtrl, Msg, wParam, lParam); wrap: // Done return lRc; }
HRESULT STDMETHODCALLTYPE playlists_tabs_extension::playlists_tabs_drop_target::DragOver(DWORD grfKeyState, POINTL ptl, DWORD *pdwEffect) { POINT pt = { ptl.x, ptl.y }; bool isAltDown = (grfKeyState & MK_ALT) != 0; if (m_DropTargetHelper.is_valid()) m_DropTargetHelper->DragOver(&pt, *pdwEffect); if (ui_drop_item_callback::g_is_accepted_type(m_DataObject.get_ptr(), pdwEffect)) return S_OK; *pdwEffect = DROPEFFECT_COPY; m_last_rmb = ((grfKeyState & MK_RBUTTON) != 0); if (last_over.x != pt.x || last_over.y != pt.y) { last_over = ptl; if (!m_is_accepted_type) { *pdwEffect = DROPEFFECT_NONE; mmh::ole::SetDropDescription(m_DataObject.get_ptr(), DROPIMAGE_INVALID, "", ""); return S_OK; } static_api_ptr_t<playlist_manager> playlist_api; POINT pti, ptm; pti.y = pt.y; pti.x = pt.x; ptm = pti; ScreenToClient(p_list->get_wnd(), &ptm); HWND wnd = ChildWindowFromPointEx(p_list->get_wnd(), ptm, CWP_SKIPINVISIBLE); // RECT plist; // GetWindowRect(g_plist, &plist); // RECT tabs; // GetWindowRect(g_tab, &tabs); if (p_list->wnd_tabs) { POINT pttab; pttab = pti; if (wnd == p_list->wnd_tabs && ScreenToClient(p_list->wnd_tabs, &pttab)) { TCHITTESTINFO hittest; hittest.pt.x = pttab.x; hittest.pt.y = pttab.y; int idx = TabCtrl_HitTest(p_list->wnd_tabs, &hittest); int old = playlist_api->get_active_playlist(); if (cfg_drag_autoswitch && idx >= 0 && old != idx && !isAltDown) p_list->switch_to_playlist_delayed2(idx);//playlist_switcher::get()->set_active_playlist(idx); else p_list->kill_switch_timer(); if (idx != -1 && !isAltDown) { pfc::string8 name; static_api_ptr_t<playlist_manager>()->playlist_get_name(idx, name); mmh::ole::SetDropDescription(m_DataObject.get_ptr(), DROPIMAGE_COPY, "Add to %1", name); } else mmh::ole::SetDropDescription(m_DataObject.get_ptr(), DROPIMAGE_COPY, "Add to new playlist", ""); } else mmh::ole::SetDropDescription(m_DataObject.get_ptr(), DROPIMAGE_COPY, "Add to new playlist", ""); } if ((!p_list->wnd_tabs || wnd != p_list->wnd_tabs)) p_list->kill_switch_timer(); } return S_OK; }
HRESULT STDMETHODCALLTYPE playlists_tabs_extension::playlists_tabs_drop_target::Drop(IDataObject *pDataObj, DWORD grfKeyState, POINTL ptl, DWORD *pdwEffect) { POINT pt = { ptl.x, ptl.y }; bool isAltDown = (grfKeyState & MK_ALT) != 0; if (m_DropTargetHelper.is_valid()) m_DropTargetHelper->Drop(pDataObj, &pt, *pdwEffect); p_list->kill_switch_timer(); m_DataObject.release(); last_over.x = 0; last_over.y = 0; if (!m_is_accepted_type) { mmh::ole::SetDropDescription(m_DataObject.get_ptr(), DROPIMAGE_INVALID, "", ""); return S_OK; } static_api_ptr_t<playlist_manager> playlist_api; POINT pti, ptm; pti.y = pt.y; pti.x = pt.x; ptm = pti; ScreenToClient(p_list->get_wnd(), &ptm); HWND wnd = ChildWindowFromPointEx(p_list->get_wnd(), ptm, CWP_SKIPINVISIBLE); if (wnd) { bool process = !ui_drop_item_callback::g_on_drop(pDataObj); bool send_new_playlist = false; if (process && m_last_rmb) { process = false; enum { ID_DROP = 1, ID_NEW_PLAYLIST, ID_CANCEL }; HMENU menu = CreatePopupMenu(); uAppendMenu(menu, (MF_STRING), ID_DROP, "&Add files here"); uAppendMenu(menu, (MF_STRING), ID_NEW_PLAYLIST, "&Add files to new playlist"); uAppendMenu(menu, MF_SEPARATOR, 0, 0); uAppendMenu(menu, MF_STRING, ID_CANCEL, "&Cancel"); int cmd = TrackPopupMenu(menu, TPM_RIGHTBUTTON | TPM_NONOTIFY | TPM_RETURNCMD, pt.x, pt.y, 0, p_list->get_wnd(), 0); DestroyMenu(menu); if (cmd) { switch (cmd) { case ID_DROP: process = true; break; case ID_NEW_PLAYLIST: process = true; send_new_playlist = true; break; } } } if (process) { metadb_handle_list data; static_api_ptr_t<playlist_incoming_item_filter> incoming_api; incoming_api->process_dropped_files(pDataObj, data, true, p_list->get_wnd()); POINT pttab, ptpl; pttab = pti; ptpl = pti; int idx = -1; t_size newPlaylistIndex = pfc_infinite; // if ((g_tab && wnd == g_tab) || g_plist && wnd == g_plist) // bool processed = false; t_size target_index = playlist_api->get_active_playlist(); if (p_list->wnd_tabs && wnd == p_list->wnd_tabs) { RECT tabs; GetWindowRect(p_list->wnd_tabs, &tabs); if (ScreenToClient(p_list->wnd_tabs, &pttab)) { TCHITTESTINFO hittest; hittest.pt.x = pttab.x; hittest.pt.y = pttab.y; int idx = TabCtrl_HitTest(p_list->wnd_tabs, &hittest); int old = playlist_api->get_active_playlist(); if (send_new_playlist || idx < 0 || isAltDown) { send_new_playlist = true; if (idx >= 0) newPlaylistIndex = idx; } else target_index = idx; } } if (send_new_playlist) { pfc::string8 playlist_name("Untitled"); bool named = false; if (1 || 1) { FORMATETC fe; STGMEDIUM sm; HRESULT hr = E_FAIL; // memset(&sm, 0, sizeof(0)); fe.cfFormat = CF_HDROP; fe.ptd = NULL; fe.dwAspect = DVASPECT_CONTENT; fe.lindex = -1; fe.tymed = TYMED_HGLOBAL; // User has dropped on us. Get the data from drag source hr = pDataObj->GetData(&fe, &sm); if (SUCCEEDED(hr)) { // Display the data and release it. pfc::string8 temp; unsigned int /*n,*/t = uDragQueryFileCount((HDROP)sm.hGlobal); if (t == 1) { { uDragQueryFile((HDROP)sm.hGlobal, 0, temp); if (uGetFileAttributes(temp) & FILE_ATTRIBUTE_DIRECTORY) { playlist_name.set_string(pfc::string_filename_ext(temp)); named = true; } else { playlist_name.set_string(pfc::string_filename(temp)); named = true; #if 0 pfc::string_extension ext(temp); service_enum_t<playlist_loader> e; service_ptr_t<playlist_loader> l; if (e.first(l)) do { if (!strcmp(l->get_extension(), ext)) { playlist_name.set_string(pfc::string_filename(temp)); named = true; l.release(); break; } l.release(); } while (e.next(l)); #endif } } } ReleaseStgMedium(&sm); } } unsigned new_idx; if (newPlaylistIndex == pfc_infinite) newPlaylistIndex = playlist_api->get_playlist_count(); if (named && cfg_replace_drop_underscores) playlist_name.replace_char('_', ' ', 0); if (!named && cfg_pgen_tf) new_idx = playlist_api->create_playlist(string_pn(data, cfg_pgenstring), pfc_infinite, newPlaylistIndex); else new_idx = playlist_api->create_playlist(playlist_name, pfc_infinite, newPlaylistIndex); playlist_api->playlist_add_items(new_idx, data, bit_array_false()); if (main_window::config_get_activate_target_playlist_on_dropped_items()) playlist_api->set_active_playlist(new_idx); } else { playlist_api->playlist_clear_selection(target_index); playlist_api->playlist_insert_items(target_index, idx, data, bit_array_true()); if (main_window::config_get_activate_target_playlist_on_dropped_items()) playlist_api->set_active_playlist(target_index); } data.remove_all(); } } return S_OK; }
int iupwinBaseContainerMsgProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *result) { /* All messages here are sent to the parent Window, but they are useful for child controls. */ switch (msg) { case WM_COMMAND: { Ihandle* child = winContainerWmCommandGetIhandle(ih, wp, lp); if (child) { IFwmCommand cb = (IFwmCommand)IupGetCallback(child, "_IUPWIN_COMMAND_CB"); if (cb) cb(child, wp, lp); } break; } case WM_CTLCOLOREDIT: case WM_CTLCOLORLISTBOX: case WM_CTLCOLORBTN: case WM_CTLCOLORSCROLLBAR: case WM_CTLCOLORSTATIC: { Ihandle* child = iupwinHandleGet((HWND)lp); if (child && winCheckParent(child, ih)) { IFctlColor cb = (IFctlColor)IupGetCallback(child, "_IUPWIN_CTLCOLOR_CB"); if (cb) return cb(child, (HDC)wp, result); } break; } case WM_DRAWITEM: /* for OWNERDRAW controls */ { Ihandle *child; DRAWITEMSTRUCT *drawitem = (LPDRAWITEMSTRUCT)lp; if (!drawitem) break; if (wp == 0) /* a menu */ child = iupwinMenuGetItemHandle((HMENU)drawitem->hwndItem, drawitem->itemID); else { child = iupwinHandleGet(drawitem->hwndItem); if (child && !winCheckParent(child, ih)) child = NULL; } if (child) { IFdrawItem cb = (IFdrawItem)IupGetCallback(child, "_IUPWIN_DRAWITEM_CB"); if (cb) { cb(child, (void*)drawitem); *result = TRUE; return 1; } } break; } case WM_HSCROLL: case WM_VSCROLL: { Ihandle *child = iupwinHandleGet((HWND)lp); if (child && winCheckParent(child, ih)) { IFni cb = (IFni)IupGetCallback(child, "_IUPWIN_CUSTOMSCROLL_CB"); if (cb) cb(child, LOWORD(wp)); } break; } case WM_NOTIFY: /* Currently, the following controls support custom draw functionality: Header, List-view, Rebar, Toolbar, ToolTip, Trackbar, Tree-view. And for Button if using Windows XP Style. */ { Ihandle *child; NMHDR* msg_info = (NMHDR*)lp; if (!msg_info) break; child = iupwinHandleGet(msg_info->hwndFrom); if (child && winCheckParent(child, ih)) { IFnotify cb = (IFnotify)IupGetCallback(child, "_IUPWIN_NOTIFY_CB"); if (cb) { int ret; if (cb(child, (void*)msg_info, &ret)) { *result = (LRESULT)ret; return 1; } } } break; } case WM_MOUSEWHEEL: { HWND hChild; POINT p; p.x = GET_X_LPARAM(lp); p.y = GET_Y_LPARAM(lp); ScreenToClient(ih->handle, &p); hChild = ChildWindowFromPointEx(ih->handle, p, CWP_SKIPDISABLED|CWP_SKIPINVISIBLE|CWP_SKIPTRANSPARENT); if (hChild) { Ihandle* child = iupwinHandleGet(hChild); if (child && IupClassMatch(child, "canvas")) /* will check of all canvas based control classes */ SendMessage(child->handle, WM_MOUSEWHEEL, wp, lp); } break; } default: { /* sent to the list parent */ if (msg == WM_DRAGLISTMSG) { DRAGLISTINFO* lpDrag = (DRAGLISTINFO*) lp; Ihandle *child = iupwinHandleGet(lpDrag->hWnd); if (child && winCheckParent(child, ih)) { *result = iupwinListDND(child, lpDrag->uNotification, lpDrag->ptCursor); return 1; } } break; } } return iupwinBaseMsgProc(ih, msg, wp, lp, result); }
int fnHitTest(HWND hwnd, struct ClcData *dat, int testx, int testy, ClcContact **contact, ClcGroup **group, DWORD * flags) { ClcContact *hitcontact = NULL; ClcGroup *hitgroup = NULL; int indent, i; DWORD style = GetWindowLongPtr(hwnd, GWL_STYLE); if (flags) *flags = 0; POINT pt; pt.x = testx; pt.y = testy; ClientToScreen(hwnd, &pt); HWND hwndParent = hwnd, hwndTemp; do { hwndTemp = hwndParent; hwndParent = (HWND)GetWindowLongPtr(hwndTemp, GWLP_HWNDPARENT); POINT pt1 = pt; ScreenToClient(hwndParent, &pt1); HWND h = ChildWindowFromPointEx(hwndParent ? hwndParent : GetDesktopWindow(), pt1, CWP_SKIPINVISIBLE | CWP_SKIPTRANSPARENT); if (h != hwndTemp) if (!hwndParent || !(GetWindowLongPtr(hwndTemp, GWL_STYLE) & BS_GROUPBOX)) return -1; } while (hwndParent); RECT clRect; GetClientRect(hwnd, &clRect); if (testx < 0 || testy < 0 || testy >= clRect.bottom || testx >= clRect.right) { if (flags) { if (testx < 0) *flags |= CLCHT_TOLEFT; else if (testx >= clRect.right) *flags |= CLCHT_TORIGHT; if (testy < 0) *flags |= CLCHT_ABOVE; else if (testy >= clRect.bottom) *flags |= CLCHT_BELOW; } return -1; } if (testx < dat->leftMargin) { if (flags) *flags |= CLCHT_INLEFTMARGIN | CLCHT_NOWHERE; return -1; } int hit = cli.pfnRowHitTest(dat, dat->yScroll + testy); if (hit != -1) hit = cli.pfnGetRowByIndex(dat, hit, &hitcontact, &hitgroup); if (hit == -1) { if (flags) *flags |= CLCHT_NOWHERE | CLCHT_BELOWITEMS; return -1; } if (contact) *contact = hitcontact; if (group) *group = hitgroup; for (indent = 0; hitgroup->parent; indent++, hitgroup = hitgroup->parent); if (testx < dat->leftMargin + indent * dat->groupIndent) { if (flags) *flags |= CLCHT_ONITEMINDENT; return hit; } int checkboxWidth = 0; if (style & CLS_CHECKBOXES && hitcontact->type == CLCIT_CONTACT) checkboxWidth = dat->checkboxSize + 2; if (style & CLS_GROUPCHECKBOXES && hitcontact->type == CLCIT_GROUP) checkboxWidth = dat->checkboxSize + 2; if (hitcontact->type == CLCIT_INFO && hitcontact->flags & CLCIIF_CHECKBOX) checkboxWidth = dat->checkboxSize + 2; if (testx < dat->leftMargin + indent * dat->groupIndent + checkboxWidth) { if (flags) *flags |= CLCHT_ONITEMCHECK; return hit; } if (testx < dat->leftMargin + indent * dat->groupIndent + checkboxWidth + dat->iconXSpace) { if (flags) *flags |= CLCHT_ONITEMICON; return hit; } int eiOffset = 0; for (i = dat->extraColumnsCount-1; i >= 0; i--) { if (hitcontact->iExtraImage[i] == EMPTY_EXTRA_ICON) continue; eiOffset += dat->extraColumnSpacing; if (testx >= clRect.right - eiOffset && testx < clRect.right - eiOffset + g_IconWidth) { if (flags) *flags |= CLCHT_ONITEMEXTRA | (i << 24); return hit; } } HDC hdc = GetDC(hwnd); HFONT hFont = (HFONT)SelectObject(hdc, dat->fontInfo[hitcontact->type == CLCIT_GROUP ? FONTID_GROUPS : FONTID_CONTACTS].hFont); SIZE textSize; GetTextExtentPoint32(hdc, hitcontact->szText, lstrlen(hitcontact->szText), &textSize); int width = textSize.cx; if (hitcontact->type == CLCIT_GROUP) { char *szCounts; szCounts = cli.pfnGetGroupCountsText(dat, hitcontact); if (szCounts[0]) { GetTextExtentPoint32A(hdc, " ", 1, &textSize); width += textSize.cx; SelectObject(hdc, dat->fontInfo[FONTID_GROUPCOUNTS].hFont); GetTextExtentPoint32A(hdc, szCounts, lstrlenA(szCounts), &textSize); width += textSize.cx; } } SelectObject(hdc, hFont); ReleaseDC(hwnd, hdc); if (testx < dat->leftMargin + indent * dat->groupIndent + checkboxWidth + dat->iconXSpace + width + 4) { if (flags) *flags |= CLCHT_ONITEMLABEL; return hit; } if (flags) *flags |= CLCHT_NOWHERE; return -1; }