From 0c3d3e587e699d06352f269d887d749a8542559a Mon Sep 17 00:00:00 2001 From: sje Date: Wed, 1 Nov 2006 14:58:39 +0000 Subject: git-svn-id: https://server.scottellis.com.au/svn/mim_plugs@26 4f64403b-2f21-0410-a795-97e2b3489a10 --- yapp/message_pump.cpp | 160 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 yapp/message_pump.cpp (limited to 'yapp/message_pump.cpp') diff --git a/yapp/message_pump.cpp b/yapp/message_pump.cpp new file mode 100644 index 0000000..f5cedd8 --- /dev/null +++ b/yapp/message_pump.cpp @@ -0,0 +1,160 @@ +#include "common.h" +#include "message_pump.h" +#include "popwin.h" +#include "services.h" +#include "options.h" + +DWORD message_pump_thread_id = 0; +int num_popups = 0; + +HANDLE hMPEvent; + +#define MUM_FINDWINDOW (WM_USER + 0x050) + +#define MAX_POPUPS 100 + +// from popups, popup2 implementation +bool is_full_screen() { + HWND hWnd = GetForegroundWindow(); + + if(!hWnd || !IsWindowVisible(hWnd) || IsIconic(hWnd) || !IsZoomed(hWnd)) return false; + + RECT rc; + if(!GetWindowRect(hWnd,&rc)) return false; + + if (rc.right - rc.left < GetSystemMetrics(SM_CXSCREEN) || rc.bottom - rc.top < GetSystemMetrics(SM_CYSCREEN)) return false; + + // at this point, it will return true for full-screen and, unfortunately, maximized windows - so we need to check for maximized + + LONG style = GetWindowLong(hWnd, GWL_STYLE); + if(style & WS_MAXIMIZEBOX) return false; + + return true; +} + +bool is_workstation_locked() +{ + bool rc = false; + HDESK hDesk = OpenDesktop(_T("default"), 0, FALSE, DESKTOP_SWITCHDESKTOP); + if(hDesk != 0) { + HDESK hDeskInput = OpenInputDesktop(0, FALSE, DESKTOP_SWITCHDESKTOP); + if(hDeskInput == 0) { + rc = true; + } else + CloseDesktop(hDeskInput); + + CloseDesktop(hDesk); + } + + return rc; +} + + +DWORD CALLBACK MessagePumpThread(LPVOID param) { + CallService(MS_SYSTEM_THREAD_PUSH, 0, 0); + + InitWindowStack(); + + if(param) SetEvent((HANDLE)param); + + MSG hwndMsg = {0}; + while(GetMessage(&hwndMsg, 0, 0, 0) > 0 && !Miranda_Terminated()) { + if(!IsDialogMessage(hwndMsg.hwnd, &hwndMsg)) { + switch(hwndMsg.message) { + case MUM_CREATEPOPUP: + { + bool enabled = true; + int status = CallService(MS_CLIST_GETSTATUSMODE, 0, 0); + if(status >= ID_STATUS_OFFLINE && status <= ID_STATUS_OUTTOLUNCH && options.disable_status[status - ID_STATUS_OFFLINE]) + enabled = false; + if(options.disable_full_screen && is_full_screen() || is_workstation_locked()) + enabled = false; + if(enabled && num_popups < MAX_POPUPS) { + //HWND hwnd = CreateWindowEx(WS_EX_TOOLWINDOW | WS_EX_TOPMOST, POP_WIN_CLASS, _T("Popup"), WS_POPUP, 0, 0, 0, 0, GetDesktopWindow(), 0, hInst, (LPVOID)hwndMsg.lParam); + HWND hwnd = CreateWindowEx(WS_EX_TOOLWINDOW | WS_EX_TOPMOST, POP_WIN_CLASS, _T("Popup"), WS_POPUP, 0, 0, 0, 0, 0, 0, hInst, (LPVOID)hwndMsg.lParam); + num_popups++; + if(hwndMsg.wParam) // set notifyer handle + SendMessage(hwnd, PUM_SETNOTIFYH, hwndMsg.wParam, 0); + } else { + free((void *)hwndMsg.lParam); + } + } + break; + + case MUM_DELETEPOPUP: + { + HWND hwnd = (HWND)hwndMsg.lParam; + if(IsWindow(hwnd)) { + DestroyWindow(hwnd); + num_popups--; + } + } + break; + case MUM_NMUPDATE: + { + HANDLE hNotify = (HANDLE)hwndMsg.wParam; + BroadcastMessage(PUM_UPDATENOTIFY, (WPARAM)hNotify, 0); + } + break; + case MUM_NMREMOVE: + { + HANDLE hNotify = (HANDLE)hwndMsg.wParam; + BroadcastMessage(PUM_KILLNOTIFY, (WPARAM)hNotify, 0); + } + break; + default: + { + TranslateMessage(&hwndMsg); + DispatchMessage(&hwndMsg); + // do this here in case the window has gone + if(hwndMsg.message == PUM_CHANGE || hwndMsg.message == PUM_SETTEXT) + free((void *)hwndMsg.lParam); + } + break; + } + } + } + + DeinitWindowStack(); + num_popups = 0; + + //if(param) SetEvent((HANDLE)param); + + CallService(MS_SYSTEM_THREAD_POP, 0, 0); + + return 0; +} + +void PostMPMessage(UINT msg, WPARAM wParam, LPARAM lParam) { + PostThreadMessage(message_pump_thread_id, msg, wParam, lParam); +} + +// given a popup data pointer, and a handle to an event, this function +// will post a message to the message queue which will set the hwnd value +// and then set the event...so create an event, call this function and then wait on the event +// when the event is signalled, the hwnd will be valid +void FindWindow(POPUPDATAW *pd, HANDLE hEvent, HWND *hwnd); + +void InitMessagePump() { + WNDCLASS popup_win_class = {0}; + popup_win_class.style = 0; + popup_win_class.lpfnWndProc = PopupWindowProc; + popup_win_class.hInstance = hInst; + popup_win_class.lpszClassName = POP_WIN_CLASS; + popup_win_class.hCursor = LoadCursor(NULL, IDC_ARROW); + RegisterClass(&popup_win_class); + + InitServices(); + + hMPEvent = CreateEvent(0, TRUE, 0, 0); + CloseHandle(CreateThread(0, 0, MessagePumpThread, hMPEvent, 0, &message_pump_thread_id)); + WaitForSingleObject(hMPEvent, INFINITE); + CloseHandle(hMPEvent); +} + +void DeinitMessagePump() { + + PostMPMessage(WM_QUIT, 0, 0); + + DeinitServices(); +} -- cgit v1.2.3