时间:2023-07-25 02:09:01 | 来源:网站运营
时间:2023-07-25 02:09:01 来源:网站运营
自定义·自制HTML壁纸:本文很大程度上基于 @今晚的风儿很喧嚣 的文章 今晚的风儿很喧嚣:手写一个 windows 桌面动态壁纸(以下简称“参考文献1”) *hDesktop = FindWindowA("Progman", "Program Manager"); SendMessageA(*hDesktop, WM_USER + 300, 0, 0);
啊,我这个笨蛋没有做错误处理,大家不要学我。 SetParent(reinterpret_cast<HWND>(item->winId()),hDesktop); ShowWindow(hWorkerX,SW_SHOW); EnableWindow(hWorkerX,TRUE);
然后,我们试图截获桌面上的鼠标按键。LRESULT CALLBACK MouseProc(_In_ int nCode, _In_ WPARAM wParam, _In_ LPARAM lParam) { //according to MSDN, when nCode<0, do nothing if (nCode < 0)return CallNextHookEx(hHook, nCode, wParam, lParam); //when middle button is released, hide the desktop. if (wParam == WM_MBUTTONUP) { ShowWindow(WorkerW, SW_HIDE); return 1; } //passing mouse actions: it can not handle properly when you drag. if ((wParam == WM_LBUTTONDOWN)|| (wParam == WM_LBUTTONUP)|| (wParam == WM_LBUTTONDBLCLK)||(wParam==WM_MOUSEMOVE)) { MOUSEHOOKSTRUCT *in = reinterpret_cast<MOUSEHOOKSTRUCT*>(lParam); if(in->pt.x) PostMessage(Recv, MsgCode, wParam, MAKELPARAM(in->pt.x, in->pt.y)); } return CallNextHookEx(hHook, nCode, wParam, lParam);}
大概的意思是,如果点击鼠标中键,则隐藏桌面图标。而对左键的动作,保留原有处理方式并转发给我们的窗口。#pragma data_seg("Shared")......//待定义的变量们#pragma data_seg()
然后,我们就可以使用SetWindowsHookEx进行挂钩了。BOOL StartHook(_In_ HWND pIcons, _In_ HWND pWorkerW, _In_ HWND pRecv) { //Hook into the window with icons. DWORD tid = GetWindowThreadProcessId(pIcons, NULL); if (tid == 0)return FALSE; hHook = SetWindowsHookEx(WH_MOUSE, MouseProc, Me, tid); if (hHook == 0)return FALSE; //make sure the icons are shown. ShowWindow(WorkerW, SW_SHOW); //Retrieve necessary data. Icons = pIcons; WorkerW = pWorkerW; Recv = pRecv; return TRUE;}void StopHook(){ //clear data up. Icons = 0; WorkerW = 0; Recv = 0; //make sure that the icons are shown ShowWindow(WorkerW, SW_SHOW); //release the hooks UnhookWindowsHookEx(hHook); hHook = 0;}
好的。这样子我们就成功地截获了Windows鼠标消息。LIBRARY OpenDesktopEXPORTS MouseProc StartHook StopHook FindWindows SECTIONS Shared READ WRITE SHARED
然后,我们在使用时则需要通过LoadLibrary加载dll,之后利用GetProcAddress获得函数地址。 bool initDll(){ list.clear(); map.clear(); hDll=LoadLibraryA("OpenDesktop.dll"); if(hDll==nullptr)return false; FARPROC hFun1 = GetProcAddress(hDll, "StartHook"); FARPROC hFun2 = GetProcAddress(hDll, "FindWindows"); FARPROC hFun3 = GetProcAddress(hDll, "StopHook"); StartHook=reinterpret_cast<STARTHOOK>(hFun1); FindWindows=reinterpret_cast<FINDWINDOWS>(hFun2); StopHook=reinterpret_cast<STOPHOOK>(hFun3); if((StartHook==nullptr)||(FindWindows==nullptr)||(StopHook==nullptr))return false; return true; }
其中几个我们不认识的类型定义如下:typedef BOOL (*STARTHOOK)(HWND,HWND,HWND);typedef BOOL (*FINDWINDOWS)(HWND*,HWND*,HWND*);typedef BOOL (*STOPHOOK)();
之后就是直截了当的当作正常函数那样调用就好了啦。UINT TaskbarCreated=RegisterWindowMessageA("TaskbarCreated");
之后只要聆听这个消息就好了啦…它会自动推送给所有有条件接收消息的顶级窗口的。LRESULT CALLBACK WindowProc( _In_ HWND hwnd, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ){ if(uMsg==TaskbarCreated)Explorer::init(); if(uMsg==CustomMessage){ //Building the mouse event to send. QPoint pt(LOWORD(lParam),HIWORD(lParam)); Explorer::DispatchMouseMessage(pt,wParam); }; return DefWindowProcA(hwnd,uMsg,wParam,lParam);}
首先我们构造这个窗口的窗口过程,并在其中处理消息。这里我们处理了Explorer重建的消息和自定义鼠标事件的消息。 WNDCLASS winclass; winclass.style=NULL; winclass.lpfnWndProc=WindowProc; winclass.cbClsExtra=NULL; winclass.cbWndExtra=NULL; winclass.hInstance=GetModuleHandleA(nullptr); winclass.hIcon=nullptr; winclass.hCursor=nullptr; winclass.hbrBackground=nullptr; winclass.lpszMenuName=nullptr; winclass.lpszClassName=L"DesktopMessageListener"; RegisterClass(&winclass);
大概的意思就是…除了必要的参数之外,剩下的都一律写0. Listener=CreateWindowA( "DesktopMessageListener", nullptr, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,CW_USEDEFAULT, CW_USEDEFAULT,CW_USEDEFAULT, nullptr,nullptr,GetModuleHandleA(nullptr),nullptr); if(Listener==nullptr)return false;
最后我们把它隐藏好 ShowWindow(Listener,SW_HIDE);
这样子,我们就完成了事件监听窗口的建立。bool WebPage::event(QEvent *e){ //Events to a WebEngineView should be handled by a RenderWidgetHostViewQtDelegateWidget if (e->type() == QEvent::ChildPolished) { QChildEvent *child_ev = static_cast<QChildEvent*>(e); childObj = child_ev->child(); } return QWebEngineView::event(e);}
而通过以下的方式将事件发送给孩子void WebPage::SendToChild(QEvent *e){ QApplication::sendEvent(childObj,e);}
最后的最后,加入防止重复运行的方式…关键词:定义