From a13e82647294da4add976a24335fec50d7bfe905 Mon Sep 17 00:00:00 2001 From: sje Date: Wed, 1 Nov 2006 14:46:09 +0000 Subject: git-svn-id: https://server.scottellis.com.au/svn/mim_plugs@15 4f64403b-2f21-0410-a795-97e2b3489a10 --- tipper/message_pump.cpp | 201 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 tipper/message_pump.cpp (limited to 'tipper/message_pump.cpp') diff --git a/tipper/message_pump.cpp b/tipper/message_pump.cpp new file mode 100644 index 0000000..d891a33 --- /dev/null +++ b/tipper/message_pump.cpp @@ -0,0 +1,201 @@ +#include "common.h" +#include "message_pump.h" +#include "popwin.h" +#include "options.h" + +HMODULE hUserDll; +BOOL (WINAPI *MySetLayeredWindowAttributes)(HWND,COLORREF,BYTE,DWORD) = 0; +BOOL (WINAPI *MyAnimateWindow)(HWND hWnd,DWORD dwTime,DWORD dwFlags) = 0; + +//DWORD message_pump_thread_id = 0; +unsigned int message_pump_thread_id = 0; +HANDLE hMPEvent; + +//DWORD CALLBACK MessagePumpThread(LPVOID param) { +unsigned int CALLBACK MessagePumpThread(void *param) { + if(param) SetEvent((HANDLE)param); + + CallService(MS_SYSTEM_THREAD_PUSH, 0, 0); + + HWND hwndTip = 0; + + MSG hwndMsg = {0}; + while(GetMessage(&hwndMsg, 0, 0, 0) > 0 && !Miranda_Terminated()) { + if(!IsDialogMessage(hwndMsg.hwnd, &hwndMsg)) { + switch(hwndMsg.message) { + case MUM_CREATEPOPUP: + { + if(hwndTip) DestroyWindow(hwndTip); + // if child of clist, zorder is right, but it steals the first click on a contact :( + + // copy topmost exstyle from clist, since we'll put clist under tip in WM_CREATE message + //LONG clist_exstyle = GetWindowLong((HWND)CallService(MS_CLUI_GETHWND, 0, 0), GWL_EXSTYLE); + //hwndTip = CreateWindowEx((clist_exstyle & WS_EX_TOPMOST), POP_WIN_CLASS, _T("TipperPopup"), WS_POPUP, 0, 0, 0, 0, 0/*(HWND)CallService(MS_CLUI_GETHWND, 0, 0)*/, 0, hInst, (LPVOID)hwndMsg.lParam); + + hwndTip = CreateWindowEx(WS_EX_TOOLWINDOW | WS_EX_TOPMOST, POP_WIN_CLASS, _T("TipperPopup"), WS_POPUP, 0, 0, 0, 0, 0/*(HWND)CallService(MS_CLUI_GETHWND, 0, 0)*/, 0, hInst, (LPVOID)hwndMsg.lParam); + if(hwndMsg.lParam) free((LPVOID)hwndMsg.lParam); + } + break; + + case MUM_DELETEPOPUP: + { + if(hwndTip) { + DestroyWindow(hwndTip); + hwndTip = 0; + } + } + break; + case MUM_GOTSTATUS: + { + if(hwndTip) SendMessage(hwndTip, PUM_SETSTATUSTEXT, hwndMsg.wParam, hwndMsg.lParam); + else if(hwndMsg.lParam) free((void *)hwndMsg.lParam); + } + break; + case MUM_GOTAVATAR: + { + if(hwndTip) SendMessage(hwndTip, PUM_SETAVATAR, hwndMsg.wParam, hwndMsg.lParam); + } + break; + default: + { + TranslateMessage(&hwndMsg); + DispatchMessage(&hwndMsg); + } + break; + } + } + } + + 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); + + hUserDll = LoadLibrary(_T("user32.dll")); + if (hUserDll) { + MySetLayeredWindowAttributes = (BOOL (WINAPI *)(HWND,COLORREF,BYTE,DWORD))GetProcAddress(hUserDll, "SetLayeredWindowAttributes"); + MyAnimateWindow=(BOOL (WINAPI*)(HWND,DWORD,DWORD))GetProcAddress(hUserDll,"AnimateWindow"); + } + + hMPEvent = CreateEvent(0, TRUE, 0, 0); + CloseHandle((HANDLE)_beginthreadex(0, 0, MessagePumpThread, hMPEvent, 0, &message_pump_thread_id)); + WaitForSingleObject(hMPEvent, INFINITE); + CloseHandle(hMPEvent); +} + +void DeinitMessagePump() { + PostMPMessage(WM_QUIT, 0, 0); + + FreeLibrary(hUserDll); + + UnregisterClass(POP_WIN_CLASS, hInst); +} + +int ShowTip(WPARAM wParam, LPARAM lParam) { + CLCINFOTIP *clcit = (CLCINFOTIP *)lParam; + if(clcit->isGroup) return 0; // no group tips (since they're pretty useless) + if(clcit->isTreeFocused == 0 && options.show_no_focus == false) return 0; + + CLCINFOTIPEX *clcit2 = (CLCINFOTIPEX *)malloc(sizeof(CLCINFOTIPEX)); + memcpy(clcit2, clcit, sizeof(CLCINFOTIP)); + clcit2->cbSize = sizeof(CLCINFOTIPEX); + clcit2->proto = 0; + clcit2->text = 0; + + if(wParam) { // wParam is char pointer containing text - e.g. status bar tooltip + int size = MultiByteToWideChar(code_page, 0, (char *)wParam, -1, 0, 0); + if(size) { + clcit2->text = (wchar_t *)malloc(size * sizeof(wchar_t)); + MultiByteToWideChar(code_page, 0, (char *)wParam, -1, clcit2->text, size); + GetCursorPos(&clcit2->ptCursor); // cursor pos broken? + } + } + + PostMPMessage(MUM_CREATEPOPUP, 0, (LPARAM)clcit2); + return 1; +} + +int ShowTipW(WPARAM wParam, LPARAM lParam) { + CLCINFOTIP *clcit = (CLCINFOTIP *)lParam; + if(clcit->isGroup) return 0; // no group tips (since they're pretty useless) + if(clcit->isTreeFocused == 0 && options.show_no_focus == false) return 0; + + CLCINFOTIPEX *clcit2 = (CLCINFOTIPEX *)malloc(sizeof(CLCINFOTIPEX)); + memcpy(clcit2, clcit, sizeof(CLCINFOTIP)); + clcit2->cbSize = sizeof(CLCINFOTIPEX); + clcit2->proto = 0; + clcit2->text = 0; + + if(wParam) { // wParam is char pointer containing text - e.g. status bar tooltip + clcit2->text = _tcsdup((TCHAR *)wParam); + GetCursorPos(&clcit2->ptCursor); // cursor pos broken? + } + + PostMPMessage(MUM_CREATEPOPUP, 0, (LPARAM)clcit2); + return 1; +} + +int HideTip(WPARAM wParam, LPARAM lParam) { + //CLCINFOTIP *clcit = (CLCINFOTIP *)lParam; + PostMPMessage(MUM_DELETEPOPUP, 0, 0); + return 1; +} + +int ProtoAck(WPARAM wParam, LPARAM lParam) { + ACKDATA *ack = (ACKDATA *)lParam; + char *szMsg = (char *)ack->lParam; + if(ack->type == ACKTYPE_AWAYMSG && ack->result == ACKRESULT_SUCCESS && szMsg) { + int size = MultiByteToWideChar(code_page, 0, szMsg, -1, 0, 0); + if(size > 1) { + wchar_t *msg = (wchar_t *)malloc(size * sizeof(wchar_t)); + MultiByteToWideChar(code_page, 0, (char *) szMsg, -1, msg, size); + PostMPMessage(MUM_GOTSTATUS, (WPARAM)ack->hContact, (LPARAM)msg); + } + } + return 0; +} + +int FramesShowSBTip(WPARAM wParam, LPARAM lParam) { + if(options.status_bar_tips) { + char *proto = (char *)wParam; + + CLCINFOTIPEX *clcit2 = (CLCINFOTIPEX *)malloc(sizeof(CLCINFOTIPEX)); + memset(clcit2, 0, sizeof(CLCINFOTIPEX)); + clcit2->cbSize = sizeof(CLCINFOTIPEX); + clcit2->proto = proto; // assume static string + GetCursorPos(&clcit2->ptCursor); + + PostMPMessage(MUM_CREATEPOPUP, 0, (LPARAM)clcit2); + + return 1; + } + return 0; +} + +int FramesHideSBTip(WPARAM wParam, LPARAM lParam) { + if(options.status_bar_tips) { + PostMPMessage(MUM_DELETEPOPUP, 0, 0); + return 1; + } + return 0; +} + -- cgit v1.2.3