void InsertTabs() { HIMAGELIST hImageList1 = ImageList_Create(16, 16, ILC_MASK | ILC_COLORDDB, 3, 0); TabCtrl_SetImageList(hSelDlgTabControl, hImageList1); HICON hIcon1 = LoadIcon(hAppInst, MAKEINTRESOURCE(IDI_APP)); HICON hIcon2 = LoadIcon(hAppInst, MAKEINTRESOURCE(IDI_STAR)); HICON hIcon3 = LoadIcon(hAppInst, MAKEINTRESOURCE(IDI_COG)); ImageList_AddIcon(hImageList1, hIcon1); ImageList_AddIcon(hImageList1, hIcon2); ImageList_AddIcon(hImageList1, hIcon3); TC_ITEMHEADER TCI; TCI.mask = TCIF_TEXT | TCIF_IMAGE; TCI.pszText = _T("Games List"); TCI.iImage = 0; SendMessage(hSelDlgTabControl, TCM_INSERTITEM, (WPARAM) 0, (LPARAM) &TCI); TCI.pszText = _T("Favorite Games List"); TCI.iImage = 1; SendMessage(hSelDlgTabControl, TCM_INSERTITEM, (WPARAM) 1, (LPARAM) &TCI); TCI.pszText = _T("Options"); TCI.iImage = 2; SendMessage(hSelDlgTabControl, TCM_INSERTITEM, (WPARAM) 2, (LPARAM) &TCI); }
void Explorerplusplus::InitializeTabs(void) { /* The tab backing will hold the tab window. */ CreateTabBacking(); if(m_bForceSameTabWidth) { TabCtrlStyles |= TCS_FIXEDWIDTH; } m_hTabCtrl = CreateTabControl(m_hTabBacking,TabCtrlStyles); /* TODO: The image list is been leaked. */ HIMAGELIST himlSmall = ImageList_Create(16,16,ILC_COLOR32|ILC_MASK,0,100); AddDefaultTabIcons(himlSmall); TabCtrl_SetImageList(m_hTabCtrl,himlSmall); /* TODO: Needs to be freed when closing. */ m_pTabContainer = new CTabContainer(m_hTabCtrl,m_pShellBrowser,this); CTabDropHandler *pTabDropHandler = new CTabDropHandler(m_hTabCtrl,m_pTabContainer); RegisterDragDrop(m_hTabCtrl,pTabDropHandler); pTabDropHandler->Release(); SetWindowSubclass(m_hTabCtrl,TabSubclassProcStub,0,reinterpret_cast<DWORD_PTR>(this)); /* Create the toolbar that will appear on the tab control. Only contains the close button used to close tabs. */ TCHAR szTabCloseTip[64]; LoadString(m_hLanguageModule,IDS_TAB_CLOSE_TIP,szTabCloseTip,SIZEOF_ARRAY(szTabCloseTip)); m_hTabWindowToolbar = CreateTabToolbar(m_hTabBacking,TABTOOLBAR_CLOSE,szTabCloseTip); }
void wxNotebook::SetImageList(wxImageList* imageList) { wxNotebookBase::SetImageList(imageList); if ( imageList ) { (void) TabCtrl_SetImageList(GetHwnd(), GetHimagelistOf(imageList)); } }
void Main_OnInitDialog (HWND hDlg) { // Resize and reposition the main window // RECT rWindow = gr.rMain; if (!rWindow.right) GetWindowRect (hDlg, &rWindow); ResizeWindow (hDlg, awdMain, rwaMoveToHere, &rWindow); // Add tabs to the main window's tab control // HWND hTab = GetDlgItem (hDlg, IDC_TAB); TabCtrl_SetImageList (hTab, AfsAppLib_CreateImageList (FALSE)); TCHAR szText[ cchRESOURCE ]; TC_ITEM tci; tci.mask = TCIF_TEXT | TCIF_PARAM | TCIF_IMAGE; tci.pszText = szText; for (size_t iTab = 0; iTab < cTABS; ++iTab) { tci.iImage = aTABS[ iTab ].idiImage; tci.lParam = (LPARAM)aTABS[ iTab ].tt; GetString (tci.pszText, aTABS[ iTab ].idsText); TabCtrl_InsertItem (hTab, iTab, &tci); } // Subclass the tab control, so that we can make it forward any WM_SIZE // messages to its child window. // Subclass_AddHook (hTab, Main_TabHookProc); // Since we just subclassed this control, our new wndproc wasn't around // when the window was created. Any WM_CREATE processing we'd ordinarily // in that wndproc must therefore be done here. // WM_CREATE: RECT rTab; GetRectInParent (hTab, &rTab); ResizeWindow (hTab, awdTabChild, rwaMoveToHere, &rTab); // Select an appropriate tab and display it. // Main_PrepareTabChild (gr.iTabLast); // Tell the admin client that we're interested in any actions that occur // ULONG status; asc_ActionListen (g.idClient, g.hMain, &status); }
/// Function name : createDocumentsControl // Description : Create a new Documents control // // HWND hParentWnd : [in] Parent window for the documents tab control // CONST RECT* pRect : [in] Bounding rectangle for the new tab control // CONST UINT iControlID : [in] Control ID for the documents tab control // // Return type : Window handle of the new tab control, if successful, otherwise NULL // HWND createDocumentsControl(HWND hParentWnd, CONST RECT* pRect, CONST UINT iControlID) { DOCUMENTS_DATA* pWindowData; // Window data SIZE siCtrlSize; // Size of the new control RECT rcCtrlRect; // Rect of new control HWND hTabCtrl; // Convenience pointer // Prepare rcCtrlRect = *pRect; // Reduce size of target rectangle to create border effect InflateRect(&rcCtrlRect, -2, -2); utilConvertRectangleToSize(&rcCtrlRect, &siCtrlSize); /// Create DocumentsControl (Also creates/stores window data) hTabCtrl = CreateWindow(szDocumentsCtrlClass, TEXT("Documents Control"), WS_CHILD WITH WS_TABSTOP WITH TCS_TABS WITH TCS_MULTILINE WITH TCS_TOOLTIPS WITH WS_CLIPCHILDREN, // TCS_SINGLELINE rcCtrlRect.left, rcCtrlRect.top, siCtrlSize.cy, siCtrlSize.cy, hParentWnd, (HMENU)iControlID, getAppInstance(), NULL); // [DEBUG] ERROR_CHECK("creating documents control", hTabCtrl); // [CHECK] Ensure control was created successfully if (hTabCtrl) { // Prepare pWindowData = getDocumentsControlData(hTabCtrl); // Set font and ImageList TabCtrl_SetImageList(hTabCtrl, pWindowData->hImageList); SetWindowFont(hTabCtrl, pWindowData->hTitleFont, FALSE); /// Display window UpdateWindow(hTabCtrl); ShowWindow(hTabCtrl, SW_SHOW); // [DEBUG] DEBUG_WINDOW("Documents Control", hTabCtrl); } // Return window handle or NULL return hTabCtrl; }
bool RemoveTab(HWND TabWindow, int Index) { assert(IsWindow(TabWindow)); assert(Index >= 0); assert(Index < TabCtrl_GetItemCount(TabWindow)); TC_ITEM TabData; TabData.mask = TCIF_IMAGE | TCIF_PARAM; if(TabCtrl_GetItem(TabWindow, Index, &TabData)) { int CurIndex = TabCtrl_GetCurSel(TabWindow); assert(CurIndex >= -1); if(CurIndex != -1 && TabCtrl_DeleteItem(TabWindow, Index)) { if(TabData.iImage != -1) TabCtrl_RemoveImage(TabWindow, TabData.iImage); int Count = TabCtrl_GetItemCount(TabWindow); assert(Count >= 0); if(Count == 0) // We just removed the last one, do some addition cleanup { ShowWindow(reinterpret_cast<HWND>(TabData.lParam), SW_HIDE); HIMAGELIST ImageList = TabCtrl_GetImageList(TabWindow); if(ImageList) { ImageList_Destroy(ImageList); TabCtrl_SetImageList(TabWindow, NULL); } RemoveProp(TabWindow, PropName); } else if(Index == CurIndex) // We're deleting the currently visible tab { if(Index == Count) // Last tab Index--; TabToFront(TabWindow, Index); } SetTabThemeTexture(reinterpret_cast<HWND>(TabData.lParam), false); return true; } } return false; }
bool SetTabIcon(HWND TabWindow, int Index, HICON Icon) { assert(IsWindow(TabWindow)); assert(Index >= 0); assert(Index < TabCtrl_GetItemCount(TabWindow)); HIMAGELIST ImageList = TabCtrl_GetImageList(TabWindow); if(!ImageList) // Create a new image list { ImageList = ImageList_Create(16, 16, ILC_COLOR32 | ILC_MASK, 0, 1); TabCtrl_SetImageList(TabWindow, ImageList); } TC_ITEM TabData; TabData.mask = TCIF_IMAGE; if(TabCtrl_GetItem(TabWindow, Index, &TabData)) { if(Icon) // Add icon { if(TabData.iImage == -1) // There is no icon yet TabData.iImage = ImageList_AddIcon(ImageList, Icon); else TabData.iImage = ImageList_ReplaceIcon(ImageList, TabData.iImage, Icon); } else // Remove icon { if(TabData.iImage != -1) // Skip if there is no icon { TabCtrl_RemoveImage(TabWindow, TabData.iImage); TabData.iImage = -1; } } return TabCtrl_SetItem(TabWindow, Index, &TabData); } return false; }
void Server_PrepareTabControl (HWND hTab) { TabCtrl_SetImageList (hTab, AfsAppLib_CreateImageList (FALSE)); TCHAR szText[ cchRESOURCE ]; TC_ITEM tci; tci.mask = TCIF_TEXT | TCIF_PARAM | TCIF_IMAGE; tci.pszText = szText; for (int iTab = 0; iTab < nCHILDTABS; ++iTab) { tci.iImage = CHILDTABINFO[ iTab ].iImage; tci.lParam = (LPARAM)CHILDTABINFO[ iTab ].tab; GetString (tci.pszText, CHILDTABINFO[ iTab ].idsTabTitle); TabCtrl_InsertItem (hTab, iTab, &tci); } // subclass the TCN_ window, so that it will start sending WM_SIZE // messages to its child window. // procTabControl = GetWindowLongPtr (hTab, GWLP_WNDPROC); SetWindowLongPtr (hTab, GWLP_WNDPROC, (LONG_PTR)Server_SubclassTabControlProc); // Since we just subclassed this control, our new wndproc wasn't around // when the window was created. Any WM_CREATE processing we'd ordinarily // in that wndproc must therefore be done here. // WM_CREATE: RECT rWindow; GetRectInParent (hTab, &rWindow); ResizeWindow (hTab, awdTabChild, rwaMoveToHere, &rWindow); // Finally, select an appropriate tab and display it. // Server_DisplayTab (GetParent (hTab), gr.tabLast); }
BOOL CALLBACK DlgProcParentWindow(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { DWORD ws; struct ParentWindowData *dat; dat = (struct ParentWindowData *) GetWindowLong(hwndDlg, GWL_USERDATA); if (!dat && msg!=WM_INITDIALOG) return FALSE; switch (msg) { case WM_INITDIALOG: { HMENU hMenu; HANDLE hSContact; int savePerContact = DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SAVEPERCONTACT, SRMSGDEFSET_SAVEPERCONTACT); struct NewMessageWindowLParam *newData = (struct NewMessageWindowLParam *) lParam; dat = (struct ParentWindowData *) malloc(sizeof(struct ParentWindowData)); dat->foregroundWindow = GetForegroundWindow(); dat->hContact = newData->hContact; dat->nFlash = 0; dat->nFlashMax = DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_FLASHCOUNT, SRMSGDEFSET_FLASHCOUNT); dat->childrenCount = 0; dat->children = NULL; dat->hwnd = hwndDlg; dat->flags = g_dat->flags;// | SMF_SHOWTITLEBAR; dat->mouseLBDown = 0; dat->windowWasCascaded = 0; dat->bMinimized = 0; dat->hwndStatus = CreateWindowEx(0, STATUSCLASSNAME, NULL, WS_CHILD | WS_VISIBLE | SBARS_SIZEGRIP, 0, 0, 0, 0, hwndDlg, NULL, g_hInst, NULL); { int statwidths[4]; RECT rc; SendMessage(dat->hwndStatus, SB_SETMINHEIGHT, GetSystemMetrics(SM_CYSMICON), 0); GetWindowRect(dat->hwndStatus, &rc); /* statwidths[0] = rc.right - rc.left - SB_CHAR_WIDTH - SB_TYPING_WIDTH - SB_SENDING_WIDTH; statwidths[1] = rc.right - rc.left - SB_TYPING_WIDTH - SB_SENDING_WIDTH; //rc.right - rc.left - SB_CHAR_WIDTH; statwidths[2] = rc.right - rc.left - SB_TYPING_WIDTH; //rc.right - rc.left - SB_CHAR_WIDTH; statwidths[3] = -1; SendMessage(dat->hwndStatus, SB_SETPARTS, 4, (LPARAM) statwidths); */ statwidths[0] = rc.right - rc.left - SB_CHAR_WIDTH - SB_TYPING_WIDTH; statwidths[1] = rc.right - rc.left - SB_TYPING_WIDTH; statwidths[2] = -1; SendMessage(dat->hwndStatus, SB_SETPARTS, 3, (LPARAM) statwidths); } dat->hwndTabs = GetDlgItem(hwndDlg, IDC_TABS); dat->hwndActive = NULL; SetWindowLong(hwndDlg, GWL_USERDATA, (LONG) dat); if (g_dat->hIconList != NULL) { TabCtrl_SetImageList(dat->hwndTabs, g_dat->hIconList); } WindowList_Add(g_dat->hParentWindowList, hwndDlg, 0); dat->tabCtrlDat = (struct TabCtrlData *) malloc(sizeof(struct TabCtrlData)); dat->tabCtrlDat->bDragging = FALSE; SetWindowLong(dat->hwndTabs, GWL_USERDATA, (LONG) dat->tabCtrlDat); OldTabCtrlProc = (WNDPROC) SetWindowLong(dat->hwndTabs, GWL_WNDPROC, (LONG) TabCtrlProc); ws = GetWindowLong(dat->hwndTabs, GWL_STYLE) & ~(TCS_BOTTOM); if (dat->flags & SMF_TABSATBOTTOM) { ws |= TCS_BOTTOM; } SetWindowLong(dat->hwndTabs, GWL_STYLE, ws); ws = GetWindowLong(hwndDlg, GWL_STYLE) & ~(WS_CAPTION); if (dat->flags & SMF_SHOWTITLEBAR) { ws |= WS_CAPTION; SetWindowLong(hwndDlg, GWL_STYLE, ws); } else { RECT rc; SetWindowLong(hwndDlg, GWL_STYLE, ws); GetWindowRect(hwndDlg, &rc); SetWindowPos(hwndDlg, 0, 0, 0, rc.right - rc.left, rc.bottom - rc.top, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOSENDCHANGING); } ws = GetWindowLong(hwndDlg, GWL_EXSTYLE) & ~WS_EX_LAYERED; ws |= dat->flags & SMF_USETRANSPARENCY ? WS_EX_LAYERED : 0; SetWindowLong(hwndDlg , GWL_EXSTYLE , ws); if (dat->flags & SMF_USETRANSPARENCY) { pSetLayeredWindowAttributes(hwndDlg, RGB(255,255,255), (BYTE)(255-g_dat->inactiveAlpha), LWA_ALPHA); // RedrawWindow(hwndDlg, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN); } if (!(dat->flags & SMF_SHOWSTATUSBAR)) { ShowWindow(dat->hwndStatus, SW_HIDE); } hSContact = !(dat->flags & SMF_USETABS) && savePerContact ? dat->hContact : NULL; dat->bTopmost = DBGetContactSettingByte(hSContact, SRMMMOD, SRMSGSET_TOPMOST, SRMSGDEFSET_TOPMOST); if (ScriverRestoreWindowPosition(hwndDlg, hSContact, SRMMMOD, "", 0, SW_HIDE)) { if (ScriverRestoreWindowPosition(hwndDlg, hSContact, SRMMMOD, "", RWPF_NOSIZE, SW_HIDE)) { SetWindowPos(GetParent(hwndDlg), 0, 0, 0, 450, 300, SWP_NOZORDER | SWP_HIDEWINDOW); } else { SetWindowPos(hwndDlg, 0, 0, 0, 450, 300, SWP_NOZORDER | SWP_NOMOVE | SWP_HIDEWINDOW); } } if (!(dat->flags & SMF_USETABS)) { if (!savePerContact && DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_CASCADE, SRMSGDEFSET_CASCADE)) WindowList_Broadcast(g_dat->hParentWindowList, DM_CASCADENEWWINDOW, (WPARAM) hwndDlg, (LPARAM) & dat->windowWasCascaded); } hMenu = GetSystemMenu( hwndDlg, FALSE ); AppendMenu( hMenu, MF_SEPARATOR, 0, NULL ); if (dat->bTopmost) { AppendMenu( hMenu, MF_ENABLED | MF_CHECKED | MF_STRING, IDM_TOPMOST, TranslateT("Always On Top")); SetWindowPos(hwndDlg, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); } else { AppendMenu( hMenu, MF_ENABLED | MF_UNCHECKED | MF_STRING, IDM_TOPMOST, TranslateT("Always On Top")); } } return TRUE; case WM_GETMINMAXINFO: { MINMAXINFO *mmi = (MINMAXINFO *) lParam; SIZE size; if (GetKeyState(VK_CONTROL) & 0x8000) { WINDOWPLACEMENT wp; RECT rcDesktop; wp.length = sizeof(wp); GetWindowPlacement(hwndDlg, &wp); SystemParametersInfo(SPI_GETWORKAREA, 0, &rcDesktop, 0); mmi->ptMaxSize.x = wp.rcNormalPosition.right - wp.rcNormalPosition.left; mmi->ptMaxSize.y = rcDesktop.bottom - rcDesktop.top; mmi->ptMaxPosition.x = wp.rcNormalPosition.left; if(IsIconic(hwndDlg)) { mmi->ptMaxPosition.y = rcDesktop.top; } else { mmi->ptMaxPosition.y = 0; } } GetMinimunWindowSize(dat, &size); mmi->ptMinTrackSize.x = size.cx; mmi->ptMinTrackSize.y = size.cy; return FALSE; } case WM_SIZE: if (wParam == SIZE_MINIMIZED) { dat->bMinimized = 1; } if (IsIconic(hwndDlg)) { MoveWindow(dat->hwndActive, dat->childRect.left, dat->childRect.top, dat->childRect.right-dat->childRect.left, dat->childRect.bottom - dat->childRect.top, TRUE); } else { // } // if (!IsIconic(hwndDlg)) { int i; RECT rc, rcStatus, rcChild, rcWindow; SIZE size; dat->bMinimized = 0; GetClientRect(hwndDlg, &rc); GetWindowRect(hwndDlg, &rcWindow); rcStatus.top = rcStatus.bottom = 0; if (dat->flags & SMF_SHOWSTATUSBAR) { int statwidths[4]; GetWindowRect(dat->hwndStatus, &rcStatus); statwidths[0] = rc.right - rc.left - SB_CHAR_WIDTH - SB_TYPING_WIDTH; statwidths[1] = rc.right - rc.left - SB_TYPING_WIDTH; statwidths[2] = -1; SendMessage(dat->hwndStatus, SB_SETPARTS, 3, (LPARAM) statwidths); SendMessage(dat->hwndStatus, WM_SIZE, 0, 0); } MoveWindow(dat->hwndTabs, 0, 2, (rc.right - rc.left), (rc.bottom - rc.top) - (rcStatus.bottom - rcStatus.top) - 2, FALSE); RedrawWindow(dat->hwndTabs, NULL, NULL, RDW_INVALIDATE | RDW_FRAME | RDW_ERASE); GetMinimunWindowSize(dat, &size); if ((rcWindow.bottom-rcWindow.top) < size.cy || (rcWindow.right-rcWindow.left) < size.cx) { if ((rcWindow.bottom-rcWindow.top) < size.cy) { rcWindow.bottom = rcWindow.top + size.cy; } if ((rcWindow.right-rcWindow.left) < size.cx) { rcWindow.right = rcWindow.left + size.cx; } MoveWindow(hwndDlg, rcWindow.left, rcWindow.top, rcWindow.right - rcWindow.left, rcWindow.bottom - rcWindow.top, TRUE); } GetChildWindowRect(dat, &rcChild); memcpy(&dat->childRect, &rcChild, sizeof(RECT)); for (i=0;i<dat->childrenCount;i++) { if (dat->children[i] == dat->hwndActive) { MoveWindow(dat->children[i], rcChild.left, rcChild.top, rcChild.right-rcChild.left, rcChild.bottom - rcChild.top, TRUE); RedrawWindow(GetDlgItem(dat->children[i], IDC_LOG), NULL, NULL, RDW_INVALIDATE); } } if (dat->flags & SMF_SHOWSTATUSBAR) { RedrawWindow(dat->hwndStatus, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE); } } return FALSE; case WM_SETFOCUS: if (dat->hwndActive != NULL) { SetFocus(dat->hwndActive); } return TRUE; case WM_CLOSE: DestroyWindow(hwndDlg); return TRUE; case WM_COMMAND: switch (LOWORD(wParam)) { case IDCANCEL: //DestroyWindow(hwndDlg); return TRUE; } case WM_NOTIFY: { NMHDR* pNMHDR = (NMHDR*) lParam; if (pNMHDR->hwndFrom == dat->hwndTabs) { switch (pNMHDR->code) { case TCN_SELCHANGE: { TCITEM tci = {0}; int iSel = TabCtrl_GetCurSel(dat->hwndTabs); tci.mask = TCIF_PARAM; if (TabCtrl_GetItem(dat->hwndTabs, iSel, &tci)) { struct MessageWindowData * mdat = (struct MessageWindowData *) tci.lParam; ActivateChild(dat, mdat->hwnd); SetFocus(dat->hwndActive); } } break; case NM_RCLICK: { TCHITTESTINFO thinfo; int tabId, x, y; GetCursorPos(&thinfo.pt); x = thinfo.pt.x; y = thinfo.pt.y; ScreenToClient(dat->hwndTabs, &thinfo.pt); tabId = TabCtrl_HitTest(dat->hwndTabs, &thinfo); if (tabId != -1) { struct MessageWindowData * mwd = GetChildFromTab(dat->hwndTabs, tabId); //CallService(MS_USERINFO_SHOWDIALOG, (WPARAM) mwd->hContact, 0); HMENU hMenu = (HMENU) CallService(MS_CLIST_MENUBUILDCONTACT, (WPARAM) mwd->hContact, 0); TrackPopupMenu(hMenu, 0, x, y, 0, mwd->hwnd, NULL); DestroyMenu(hMenu); } } break; } } else if (pNMHDR->hwndFrom == dat->hwndStatus) { switch (pNMHDR->code) { case NM_CLICK: { NMMOUSE *nm=(NMMOUSE*)lParam; RECT rc; SendMessage(dat->hwndStatus, SB_GETRECT, SendMessage(dat->hwndStatus, SB_GETPARTS, 0, 0) - 1, (LPARAM)&rc); if (nm->pt.x >= rc.left) SendMessage(dat->hwndActive, DM_SWITCHUNICODE, 0, 0); } } break; } } break; case WM_DROPFILES: SendMessage(dat->hwndActive, WM_DROPFILES, wParam, lParam); break; case WM_TIMER: if (wParam == TIMERID_FLASHWND) { if ((dat->nFlash > dat->nFlashMax)) {// || ((GetActiveWindow() == hwndDlg) && (GetForegroundWindow() == hwndDlg))) { KillTimer(hwndDlg, TIMERID_FLASHWND); FlashWindow(hwndDlg, FALSE); } else if (dat->nFlash < dat->nFlashMax) { FlashWindow(hwndDlg, TRUE); dat->nFlash++; } } break; case WM_CONTEXTMENU: { if (dat->hwndStatus && dat->hwndStatus == (HWND) wParam) { RECT rc; POINT pt, pt2; GetCursorPos(&pt); pt2.x = pt.x; pt2.y = pt.y; ScreenToClient(dat->hwndStatus, &pt); SendMessage(dat->hwndStatus, SB_GETRECT, SendMessage(dat->hwndStatus, SB_GETPARTS, 0, 0) - 1, (LPARAM)&rc); if (pt.x >= rc.left && dat->hwndActive != NULL) { int codePage = (int) SendMessage(dat->hwndActive, DM_GETCODEPAGE, 0, 0); int i, iSel; for(i = 0; i < GetMenuItemCount(g_dat->hMenuANSIEncoding); i++) { CheckMenuItem (g_dat->hMenuANSIEncoding, i, MF_BYPOSITION | MF_UNCHECKED); } if(codePage == CP_ACP) { CheckMenuItem(g_dat->hMenuANSIEncoding, 0, MF_BYPOSITION | MF_CHECKED); } else { CheckMenuItem(g_dat->hMenuANSIEncoding, codePage, MF_BYCOMMAND | MF_CHECKED); } iSel = TrackPopupMenu(g_dat->hMenuANSIEncoding, TPM_RETURNCMD, pt2.x, pt2.y, 0, hwndDlg, NULL); if (iSel >= 500) { if (iSel == 500) iSel = CP_ACP; SendMessage(dat->hwndActive, DM_SETCODEPAGE, 0, iSel); } } else SendMessage(dat->hwndActive, WM_CONTEXTMENU, (WPARAM)hwndDlg, 0); } break; } case WM_ACTIVATE: if (LOWORD(wParam) == WA_INACTIVE) { ws = GetWindowLong(hwndDlg, GWL_EXSTYLE) & ~WS_EX_LAYERED; ws |= dat->flags & SMF_USETRANSPARENCY ? WS_EX_LAYERED : 0; SetWindowLong(hwndDlg , GWL_EXSTYLE , ws); if (dat->flags & SMF_USETRANSPARENCY) { pSetLayeredWindowAttributes(hwndDlg, RGB(255,255,255), (BYTE)(255-g_dat->inactiveAlpha), LWA_ALPHA); // RedrawWindow(hwndDlg, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN); } } if (LOWORD(wParam) != WA_ACTIVE) break; if (dat->hwndActive == NULL) { // do not set foreground window at all (always stay in the background !) // SendMessage(hwndDlg, DM_DEACTIVATE, 0, 0); } else { PostMessage(hwndDlg, WM_SETFOCUS, 0, 0); } case WM_MOUSEACTIVATE: if (KillTimer(hwndDlg, TIMERID_FLASHWND)) { FlashWindow(hwndDlg, FALSE); dat->nFlash = 0; } ws = GetWindowLong(hwndDlg, GWL_EXSTYLE) & ~WS_EX_LAYERED; ws |= dat->flags & SMF_USETRANSPARENCY ? WS_EX_LAYERED : 0; SetWindowLong(hwndDlg , GWL_EXSTYLE , ws); if (dat->flags & SMF_USETRANSPARENCY) { pSetLayeredWindowAttributes(hwndDlg, RGB(255,255,255), (BYTE)(255-g_dat->activeAlpha), LWA_ALPHA); // RedrawWindow(hwndDlg, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN); } break; case WM_LBUTTONDOWN: if (!IsZoomed(hwndDlg)) { POINT pt; GetCursorPos(&pt); // dat->mouseLBDown = 1; // GetCursorPos(&dat->mouseLBDownPos); return SendMessage(hwndDlg, WM_SYSCOMMAND, SC_MOVE | HTCAPTION, MAKELPARAM(pt.x, pt.y)); // SetCapture(hwndDlg); } break; case WM_LBUTTONUP: //if (dat->mouseLBDown) { // dat->mouseLBDown = 0; // ReleaseCapture(); //} break; case WM_MOUSEMOVE:/* if (dat->mouseLBDown) { POINT pt; RECT rc; GetCursorPos(&pt); GetWindowRect(hwndDlg, &rc); SetWindowPos(hwndDlg, 0, rc.left - (dat->mouseLBDownPos.x - pt.x), rc.top - (dat->mouseLBDownPos.y - pt.y), 0, 0, SWP_NOZORDER | SWP_NOSIZE); dat->mouseLBDownPos = pt; }*/ break; case WM_MOVING: { int snapPixels = 10; RECT rcDesktop; RECT *pRect = (RECT *)lParam; POINT pt; SIZE szSize = {pRect->right-pRect->left,pRect->bottom-pRect->top}; GetCursorPos(&pt); SystemParametersInfo(SPI_GETWORKAREA, 0, &rcDesktop, 0); pRect->left = pt.x-dat->mouseLBDownPos.x; pRect->top = pt.y-dat->mouseLBDownPos.y; pRect->right = pRect->left+szSize.cx; pRect->bottom = pRect->top+szSize.cy; if (!(GetAsyncKeyState(VK_CONTROL) & 0x8000)) { if(pRect->top < snapPixels && pRect->top > -snapPixels) { pRect->top = 0; pRect->bottom = szSize.cy; } if(pRect->left < snapPixels && pRect->left > -snapPixels) { pRect->left = 0; pRect->right = szSize.cx; } if(pRect->right < rcDesktop.right+snapPixels && pRect->right > rcDesktop.right-snapPixels) { pRect->right = rcDesktop.right; pRect->left = rcDesktop.right-szSize.cx; } if(pRect->bottom < rcDesktop.bottom+snapPixels && pRect->bottom > rcDesktop.bottom-snapPixels) { pRect->bottom = rcDesktop.bottom; pRect->top = rcDesktop.bottom-szSize.cy; } } } break; case WM_SYSCOMMAND: if ((wParam & 0xFFF0) == SC_MOVE) { RECT rc; GetWindowRect(hwndDlg, &rc); dat->mouseLBDownPos.x = LOWORD(lParam) - rc.left; dat->mouseLBDownPos.y = HIWORD(lParam) - rc.top; } else if (wParam == IDM_TOPMOST) { HMENU hMenu = GetSystemMenu(hwndDlg, FALSE); if (dat->bTopmost) { CheckMenuItem(hMenu, IDM_TOPMOST, MF_BYCOMMAND | MF_UNCHECKED); SetWindowPos(hwndDlg, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); dat->bTopmost = FALSE; } else { CheckMenuItem(hMenu, IDM_TOPMOST, MF_BYCOMMAND | MF_CHECKED); SetWindowPos(hwndDlg, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); dat->bTopmost = TRUE; } } break; case WM_DESTROY: { WINDOWPLACEMENT wp = { 0 }; HANDLE hContact; g_dat->hParent = NULL; SetWindowLong(hwndDlg, GWL_USERDATA, 0); WindowList_Remove(g_dat->hParentWindowList, hwndDlg); if (dat->children!=NULL) free (dat->children); free(dat->tabCtrlDat); free(dat); if (!(dat->flags & SMF_USETABS) && DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SAVEPERCONTACT, SRMSGDEFSET_SAVEPERCONTACT)) hContact = dat->hContact; else hContact = NULL; wp.length = sizeof(wp); GetWindowPlacement(hwndDlg, &wp); if (!dat->windowWasCascaded) { DBWriteContactSettingDword(hContact, SRMMMOD, "x", wp.rcNormalPosition.left); DBWriteContactSettingDword(hContact, SRMMMOD, "y", wp.rcNormalPosition.top); } DBWriteContactSettingDword(hContact, SRMMMOD, "width", wp.rcNormalPosition.right - wp.rcNormalPosition.left); DBWriteContactSettingDword(hContact, SRMMMOD, "height", wp.rcNormalPosition.bottom - wp.rcNormalPosition.top); DBWriteContactSettingByte(hContact, SRMMMOD, SRMSGSET_TOPMOST, (BYTE)dat->bTopmost); } break; case DM_DEACTIVATE: SetForegroundWindow(dat->foregroundWindow); break; case DM_ERRORDECIDED: break; case DM_STARTFLASHING: if (GetActiveWindow() != hwndDlg || GetForegroundWindow() != hwndDlg) { dat->nFlash = 0; SetTimer(hwndDlg, TIMERID_FLASHWND, TIMEOUT_FLASHWND, NULL); } break; case DM_REMOVECHILD: { RemoveChild(dat, (HWND) lParam); if (dat->childrenCount != 0) { SetFocus(dat->hwndActive); } else { DestroyWindow(hwndDlg); } } return TRUE; case DM_ADDCHILD: { struct MessageWindowData * mdat = (struct MessageWindowData *) lParam; AddChild(dat, mdat); } return TRUE; case DM_ACTIVATECHILD: // if((HWND) lParam != dat->hwndActive) { ActivateChild(dat, (HWND) lParam); // } return TRUE; case DM_ACTIVATEPREV: ActivatePrevChild(dat, (HWND) lParam); SetFocus(dat->hwndActive); return TRUE; case DM_ACTIVATENEXT: ActivateNextChild(dat, (HWND) lParam); SetFocus(dat->hwndActive); return TRUE; case DM_SENDMESSAGE: { int i; for (i=0;i<dat->childrenCount;i++) { SendMessage(dat->children[i], DM_SENDMESSAGE, wParam, lParam); } } break; case DM_OPTIONSAPPLIED: { RECT rc; dat->flags = g_dat->flags; if (!(dat->flags & SMF_SHOWSTATUSBAR)) { ShowWindow(dat->hwndStatus, SW_HIDE); } else { ShowWindow(dat->hwndStatus, SW_SHOW); } ws = GetWindowLong(hwndDlg, GWL_STYLE) & ~(WS_CAPTION); if (dat->flags & SMF_SHOWTITLEBAR) { ws |= WS_CAPTION; } SetWindowLong(hwndDlg, GWL_STYLE, ws); ws = GetWindowLong(hwndDlg, GWL_EXSTYLE)& ~WS_EX_LAYERED; ws |= dat->flags & SMF_USETRANSPARENCY ? WS_EX_LAYERED : 0; SetWindowLong(hwndDlg , GWL_EXSTYLE , ws); if (dat->flags & SMF_USETRANSPARENCY) { pSetLayeredWindowAttributes(hwndDlg, RGB(255,255,255), (BYTE)(255-g_dat->inactiveAlpha), LWA_ALPHA); // RedrawWindow(hwndDlg, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN); } ws = GetWindowLong(dat->hwndTabs, GWL_STYLE) & ~(TCS_BOTTOM); if (dat->flags & SMF_TABSATBOTTOM) { ws |= TCS_BOTTOM; } SetWindowLong(dat->hwndTabs, GWL_STYLE, ws); RedrawWindow(dat->hwndTabs, NULL, NULL, RDW_INVALIDATE); GetWindowRect(hwndDlg, &rc); SetWindowPos(hwndDlg, 0, 0, 0, rc.right - rc.left, rc.bottom - rc.top, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOSENDCHANGING); SendMessage(hwndDlg, WM_SIZE, 0, 0); //RedrawWindow(hwndDlg, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN); break; } case DM_UPDATETITLE: { struct MessageWindowData * mdat = (struct MessageWindowData *) lParam; TCITEM tci; int tabId; TCHAR *tContactName; if (mdat && mdat->hwnd == dat->hwndActive) { TCHAR *newtitle, oldtitle[256]; #if defined ( _UNICODE ) newtitle = GetWindowTitle(mdat->hContact, mdat->szProto); #else newtitle = GetWindowTitle(mdat->hContact, mdat->szProto); #endif GetWindowText(hwndDlg, oldtitle, sizeof(oldtitle)); if (lstrcmp(newtitle, oldtitle)) { //swt() flickers even if the title hasn't actually changed SetWindowText(hwndDlg, newtitle); //SendMessage(hwndDlg, WM_SIZE, 0, 0); } free(newtitle); } tabId = GetTabFromHWND(dat, mdat->hwnd); tContactName = GetTabName(mdat->hContact); tci.mask = TCIF_TEXT; tci.pszText = tContactName; TabCtrl_SetItem(dat->hwndTabs, tabId, &tci); free(tContactName); break; } case DM_UPDATEWINICON: { struct MessageWindowData * mdat = (struct MessageWindowData *) lParam; if (mdat) { if (mdat->szProto) { int i, icoIdx = 0; WORD wStatus; char *szProto = mdat->szProto; HANDLE hContact = mdat->hContact; if (strcmp(mdat->szProto, "MetaContacts") == 0 && DBGetContactSettingByte(NULL,"CLC","Meta",0) == 0) { hContact = (HANDLE)CallService(MS_MC_GETMOSTONLINECONTACT,(UINT)mdat->hContact, 0); if (hContact != NULL) { szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO,(UINT)hContact,0); } else { hContact = mdat->hContact; } } wStatus = DBGetContactSettingWord(hContact, szProto, "Status", ID_STATUS_OFFLINE); mdat->wStatus = wStatus; if (mdat->hwnd == dat->hwndActive) { if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_STATUSICON, SRMSGDEFSET_STATUSICON)) { if (mdat->showTyping && (g_dat->flags&SMF_SHOWTYPINGWIN)) { SendMessage(hwndDlg, WM_SETICON, (WPARAM) ICON_BIG, (LPARAM) g_dat->hIcons[SMF_ICON_TYPING]); } else if (mdat->showUnread && (GetActiveWindow() != hwndDlg || GetForegroundWindow() != hwndDlg)) { SendMessage(hwndDlg, WM_SETICON, (WPARAM) ICON_BIG, (LPARAM) LoadSkinnedIcon(SKINICON_EVENT_MESSAGE)); } else { SendMessage(hwndDlg, WM_SETICON, (WPARAM) ICON_BIG, (LPARAM) LoadSkinnedProtoIcon(szProto, wStatus)); } } else { SendMessage(hwndDlg, WM_SETICON, (WPARAM) ICON_BIG, (LPARAM) LoadSkinnedIcon(SKINICON_EVENT_MESSAGE)); } } SendDlgItemMessage(mdat->hwnd, IDC_USERMENU, BM_SETIMAGE, IMAGE_ICON, (LPARAM) LoadSkinnedProtoIcon(szProto, wStatus)); icoIdx = 0; for (i = 0; i < g_dat->protoNum; i++) { if (!strcmp(g_dat->protoNames[i], szProto)) { icoIdx = wStatus - ID_STATUS_OFFLINE + (ID_STATUS_OUTTOLUNCH - ID_STATUS_OFFLINE + 1) * (i +1) + 2; break; } } if (mdat->hwnd != dat->hwndActive) { if (mdat->showTyping) { icoIdx = 1; } else if (mdat->showUnread & 1) { icoIdx = 0; } } i = GetTabFromHWND(dat, mdat->hwnd); if (i>=0) { TCITEM tci; tci.mask = TCIF_IMAGE; tci.iImage = icoIdx; TabCtrl_SetItem(dat->hwndTabs, i, &tci); } } } break; } case DM_UPDATESTATUSBAR: break; case DM_SWITCHSTATUSBAR: dat->flags ^= SMF_SHOWSTATUSBAR; if (!(dat->flags & SMF_SHOWSTATUSBAR)) { ShowWindow(dat->hwndStatus, SW_HIDE); } else { ShowWindow(dat->hwndStatus, SW_SHOW); } SendMessage(hwndDlg, WM_SIZE, 0, 0); break; case DM_SWITCHTOOLBAR: { int i; dat->flags ^= SMF_SHOWBTNS; for (i=0;i<dat->childrenCount;i++) { SendMessage(dat->children[i], DM_SWITCHTOOLBAR, 0, 0); } SendMessage(hwndDlg, WM_SIZE, 0, 0); } break; case DM_SWITCHTITLEBAR: { RECT rc; dat->flags ^= SMF_SHOWTITLEBAR; ws = GetWindowLong(hwndDlg, GWL_STYLE) & ~(WS_CAPTION); if (dat->flags & SMF_SHOWTITLEBAR) { ws |= WS_CAPTION; } SetWindowLong(hwndDlg, GWL_STYLE, ws); GetWindowRect(hwndDlg, &rc); SetWindowPos(hwndDlg, 0, 0, 0, rc.right - rc.left, rc.bottom - rc.top, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOSENDCHANGING); // SendMessage(hwndDlg, WM_SIZE, 0, 0); RedrawWindow(hwndDlg, NULL, NULL, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN); } break; case DM_CASCADENEWWINDOW: if ((HWND) wParam == hwndDlg) break; { RECT rcThis, rcNew; GetWindowRect(hwndDlg, &rcThis); GetWindowRect((HWND) wParam, &rcNew); if (abs(rcThis.left - rcNew.left) < 3 && abs(rcThis.top - rcNew.top) < 3) { int offset = GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYFRAME); SetWindowPos((HWND) wParam, 0, rcNew.left + offset, rcNew.top + offset, 0, 0, SWP_NOZORDER | SWP_NOSIZE); *(int *) lParam = 1; } } break; //case DM_MESSAGESENDING: // dat->messagesInProgress += wParam ? -1 : 1; // if (dat->messagesInProgress < 0) dat->messagesInProgress = 0; // break; } return FALSE; }
// Set the image list void wxTabCtrl::SetImageList(wxImageList* imageList) { m_imageList = imageList; (void) TabCtrl_SetImageList( (HWND) GetHWND(), (HIMAGELIST) imageList->GetHIMAGELIST() ); }
BOOL CALLBACK DlgProcParentWindow(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { DWORD ws; struct ParentWindowData *dat; dat = (struct ParentWindowData *) GetWindowLong(hwndDlg, GWL_USERDATA); if (!dat && msg!=WM_INITDIALOG) return FALSE; switch (msg) { case WM_INITDIALOG: { struct NewMessageWindowLParam *newData = (struct NewMessageWindowLParam *) lParam; dat = (struct ParentWindowData *) malloc(sizeof(struct ParentWindowData)); dat->hContact = newData->hContact; dat->nFlash = 0; dat->nFlashMax = DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_FLASHCOUNT, SRMSGDEFSET_FLASHCOUNT); dat->childrenCount = 0; dat->children = NULL; dat->hwnd = hwndDlg; dat->flags = g_dat->flags;// | SMF_SHOWTITLEBAR; dat->mouseLBDown = 0; dat->windowWasCascaded = 0; dat->hwndStatus = CreateWindowEx(0, STATUSCLASSNAME, NULL, WS_CHILD | WS_VISIBLE | SBARS_SIZEGRIP, 0, 0, 0, 0, hwndDlg, NULL, g_hInst, NULL); { int statwidths[4]; RECT rc; SendMessage(dat->hwndStatus, SB_SETMINHEIGHT, GetSystemMetrics(SM_CYSMICON), 0); GetWindowRect(dat->hwndStatus, &rc); /* statwidths[0] = rc.right - rc.left - SB_CHAR_WIDTH - SB_TYPING_WIDTH - SB_SENDING_WIDTH; statwidths[1] = rc.right - rc.left - SB_TYPING_WIDTH - SB_SENDING_WIDTH; //rc.right - rc.left - SB_CHAR_WIDTH; statwidths[2] = rc.right - rc.left - SB_TYPING_WIDTH; //rc.right - rc.left - SB_CHAR_WIDTH; statwidths[3] = -1; SendMessage(dat->hwndStatus, SB_SETPARTS, 4, (LPARAM) statwidths); */ statwidths[0] = rc.right - rc.left - SB_CHAR_WIDTH - SB_TYPING_WIDTH; statwidths[1] = rc.right - rc.left - SB_TYPING_WIDTH; statwidths[2] = -1; SendMessage(dat->hwndStatus, SB_SETPARTS, 3, (LPARAM) statwidths); } dat->hwndTabs = GetDlgItem(hwndDlg, IDC_TABS); dat->hwndActive = NULL; SetWindowLong(hwndDlg, GWL_USERDATA, (LONG) dat); if (g_dat->hIconList != NULL) { TabCtrl_SetImageList(dat->hwndTabs, g_dat->hIconList); } WindowList_Add(g_dat->hParentWindowList, hwndDlg, 0); dat->tabCtrlDat = (struct TabCtrlData *) malloc(sizeof(struct TabCtrlData)); dat->tabCtrlDat->bDragging = FALSE; SetWindowLong(dat->hwndTabs, GWL_USERDATA, (LONG) dat->tabCtrlDat); OldTabCtrlProc = (WNDPROC) SetWindowLong(dat->hwndTabs, GWL_WNDPROC, (LONG) TabCtrlProc); ws = GetWindowLong(dat->hwndTabs, GWL_STYLE) & ~(TCS_BOTTOM); if (dat->flags & SMF_TABSATBOTTOM) { ws |= TCS_BOTTOM; } SetWindowLong(dat->hwndTabs, GWL_STYLE, ws); ws = GetWindowLong(hwndDlg, GWL_STYLE) & ~(WS_CAPTION); if (dat->flags & SMF_SHOWTITLEBAR) { ws |= WS_CAPTION; SetWindowLong(hwndDlg, GWL_STYLE, ws); } else { RECT rc; SetWindowLong(hwndDlg, GWL_STYLE, ws); GetWindowRect(hwndDlg, &rc); SetWindowPos(hwndDlg, 0, 0, 0, rc.right - rc.left, rc.bottom - rc.top, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOSENDCHANGING); } ws = GetWindowLong(hwndDlg, GWL_EXSTYLE) & ~WS_EX_LAYERED; ws |= dat->flags & SMF_USETRANSPARENCY ? WS_EX_LAYERED : 0; SetWindowLong(hwndDlg , GWL_EXSTYLE , ws); if (dat->flags & SMF_USETRANSPARENCY) { pSetLayeredWindowAttributes(hwndDlg, RGB(255,255,255), (BYTE)(255-g_dat->inactiveAlpha), LWA_ALPHA); // RedrawWindow(hwndDlg, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN); } //SetWindowPos(dat->hwndTabs, 0, 0, -10, 0, 0, SWP_NOSIZE | SWP_NOZORDER); if (!(dat->flags & SMF_SHOWSTATUSBAR)) { ShowWindow(dat->hwndStatus, SW_HIDE); } if (dat->flags & SMF_USETABS) { if (ScriverRestoreWindowPosition(hwndDlg, NULL, SRMMMOD, "", 0, SW_HIDE)) { SetWindowPos(hwndDlg, 0, 0, 0, 450, 300, SWP_NOZORDER | SWP_NOMOVE | SWP_HIDEWINDOW); } } else { int savePerContact = DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SAVEPERCONTACT, SRMSGDEFSET_SAVEPERCONTACT); if (ScriverRestoreWindowPosition(hwndDlg, savePerContact ? dat->hContact : NULL, SRMMMOD, "", 0, SW_HIDE)) { //if (Utils_RestoreWindowPosition(GetParent(hwndDlg), savePerContact ? dat->hContact : NULL, SRMMMOD, "")) { if (savePerContact) { if (ScriverRestoreWindowPosition(hwndDlg, NULL, SRMMMOD, "", RWPF_NOSIZE, SW_HIDE)) // if (Utils_RestoreWindowPositionNoMove(GetParent(hwndDlg), NULL, SRMMMOD, "")) SetWindowPos(GetParent(hwndDlg), 0, 0, 0, 450, 300, SWP_NOZORDER | SWP_NOMOVE); } else SetWindowPos(hwndDlg, 0, 0, 0, 450, 300, SWP_NOZORDER | SWP_NOMOVE); } if (!savePerContact && DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_CASCADE, SRMSGDEFSET_CASCADE)) WindowList_Broadcast(g_dat->hParentWindowList, DM_CASCADENEWWINDOW, (WPARAM) hwndDlg, (LPARAM) & dat->windowWasCascaded); } } return TRUE; case WM_GETMINMAXINFO: { MINMAXINFO *mmi = (MINMAXINFO *) lParam; SIZE size; GetMinimunWindowSize(dat, &size); mmi->ptMinTrackSize.x = size.cx; mmi->ptMinTrackSize.y = size.cy; return FALSE; } case WM_SIZE: if (wParam == SIZE_MINIMIZED) { dat->bMinimized = 1; } if (IsIconic(hwndDlg)) { MoveWindow(dat->hwndActive, dat->childRect.left, dat->childRect.top, dat->childRect.right-dat->childRect.left, dat->childRect.bottom - dat->childRect.top, TRUE); } else { // } // if (!IsIconic(hwndDlg)) { int i; RECT rc, rcStatus, rcChild, rcWindow; SIZE size; dat->bMinimized = 0; GetClientRect(hwndDlg, &rc); GetWindowRect(hwndDlg, &rcWindow); rcStatus.top = rcStatus.bottom = 0; if (dat->flags & SMF_SHOWSTATUSBAR) { int statwidths[4]; GetWindowRect(dat->hwndStatus, &rcStatus); statwidths[0] = rc.right - rc.left - SB_CHAR_WIDTH - SB_TYPING_WIDTH; statwidths[1] = rc.right - rc.left - SB_TYPING_WIDTH; statwidths[2] = -1; SendMessage(dat->hwndStatus, SB_SETPARTS, 3, (LPARAM) statwidths); SendMessage(dat->hwndStatus, WM_SIZE, 0, 0); } MoveWindow(dat->hwndTabs, 0, 2, (rc.right - rc.left), (rc.bottom - rc.top) - (rcStatus.bottom - rcStatus.top) - 2, FALSE); RedrawWindow(dat->hwndTabs, NULL, NULL, RDW_INVALIDATE | RDW_FRAME | RDW_ERASE); GetMinimunWindowSize(dat, &size); if ((rcWindow.bottom-rcWindow.top) < size.cy || (rcWindow.right-rcWindow.left) < size.cx) { if ((rcWindow.bottom-rcWindow.top) < size.cy) { rcWindow.bottom = rcWindow.top + size.cy; } if ((rcWindow.right-rcWindow.left) < size.cx) { rcWindow.right = rcWindow.left + size.cx; } MoveWindow(hwndDlg, rcWindow.left, rcWindow.top, rcWindow.right - rcWindow.left, rcWindow.bottom - rcWindow.top, TRUE); } GetChildWindowRect(dat, &rcChild); memcpy(&dat->childRect, &rcChild, sizeof(RECT)); for (i=0;i<dat->childrenCount;i++) { if (dat->children[i] == dat->hwndActive) { MoveWindow(dat->children[i], rcChild.left, rcChild.top, rcChild.right-rcChild.left, rcChild.bottom - rcChild.top, TRUE); RedrawWindow(GetDlgItem(dat->children[i], IDC_LOG), NULL, NULL, RDW_INVALIDATE); } } if (dat->flags & SMF_SHOWSTATUSBAR) { RedrawWindow(dat->hwndStatus, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE); } } return FALSE; case WM_SETFOCUS: SetFocus(dat->hwndActive); return TRUE; case WM_CLOSE: DestroyWindow(hwndDlg); return TRUE; case WM_COMMAND: switch (LOWORD(wParam)) { case IDCANCEL: //DestroyWindow(hwndDlg); return TRUE; } case WM_NOTIFY: { NMHDR* pNMHDR = (NMHDR*) lParam; if (pNMHDR->hwndFrom == dat->hwndTabs) { switch (pNMHDR->code) { case TCN_SELCHANGE: { TCITEM tci = {0}; int iSel = TabCtrl_GetCurSel(dat->hwndTabs); tci.mask = TCIF_PARAM; if (TabCtrl_GetItem(dat->hwndTabs, iSel, &tci)) { struct MessageWindowData * mdat = (struct MessageWindowData *) tci.lParam; ActivateChild(dat, mdat->hwnd); } } break; case NM_RCLICK: { TCHITTESTINFO thinfo; int tabId, x, y; GetCursorPos(&thinfo.pt); x = thinfo.pt.x; y = thinfo.pt.y; ScreenToClient(dat->hwndTabs, &thinfo.pt); tabId = TabCtrl_HitTest(dat->hwndTabs, &thinfo); if (tabId != -1) { struct MessageWindowData * mwd = GetChildFromTab(dat->hwndTabs, tabId); //CallService(MS_USERINFO_SHOWDIALOG, (WPARAM) mwd->hContact, 0); HMENU hMenu = (HMENU) CallService(MS_CLIST_MENUBUILDCONTACT, (WPARAM) mwd->hContact, 0); TrackPopupMenu(hMenu, 0, x, y, 0, mwd->hwnd, NULL); DestroyMenu(hMenu); } } break; } } else if (pNMHDR->hwndFrom == dat->hwndStatus) { switch (pNMHDR->code) { case NM_CLICK: { NMMOUSE *nm=(NMMOUSE*)lParam; RECT rc; SendMessage(dat->hwndStatus, SB_GETRECT, SendMessage(dat->hwndStatus, SB_GETPARTS, 0, 0) - 1, (LPARAM)&rc); if (nm->pt.x >= rc.left) SendMessage(dat->hwndActive, DM_SWITCHUNICODE, 0, 0); } } break; } } break; case WM_DROPFILES: SendMessage(dat->hwndActive, WM_DROPFILES, wParam, lParam); break; case WM_TIMER: if (wParam == TIMERID_FLASHWND) { if ((dat->nFlash > dat->nFlashMax)) {// || ((GetActiveWindow() == hwndDlg) && (GetForegroundWindow() == hwndDlg))) { KillTimer(hwndDlg, TIMERID_FLASHWND); FlashWindow(hwndDlg, FALSE); } else if (dat->nFlash < dat->nFlashMax) { FlashWindow(hwndDlg, TRUE); dat->nFlash++; } } break; case WM_CONTEXTMENU: { if (dat->hwndStatus && dat->hwndStatus == (HWND) wParam) { RECT rc; POINT pt, pt2; GetCursorPos(&pt); pt2.x = pt.x; pt2.y = pt.y; ScreenToClient(dat->hwndStatus, &pt); SendMessage(dat->hwndStatus, SB_GETRECT, SendMessage(dat->hwndStatus, SB_GETPARTS, 0, 0) - 1, (LPARAM)&rc); if (pt.x >= rc.left && dat->hwndActive != NULL) { int codePage = (int) SendMessage(dat->hwndActive, DM_GETCODEPAGE, 0, 0); int i, iSel; for(i = 0; i < GetMenuItemCount(g_dat->hMenuANSIEncoding); i++) { CheckMenuItem (g_dat->hMenuANSIEncoding, i, MF_BYPOSITION | MF_UNCHECKED); } if(codePage == CP_ACP) { CheckMenuItem(g_dat->hMenuANSIEncoding, 0, MF_BYPOSITION | MF_CHECKED); } else { CheckMenuItem(g_dat->hMenuANSIEncoding, codePage, MF_BYCOMMAND | MF_CHECKED); } iSel = TrackPopupMenu(g_dat->hMenuANSIEncoding, TPM_RETURNCMD, pt2.x, pt2.y, 0, hwndDlg, NULL); if (iSel >= 500) { if (iSel == 500) iSel = CP_ACP; SendMessage(dat->hwndActive, DM_SETCODEPAGE, 0, iSel); } } else SendMessage(dat->hwndActive, WM_CONTEXTMENU, (WPARAM)hwndDlg, 0); } break; } case WM_ACTIVATE: if (LOWORD(wParam) == WA_INACTIVE) { ws = GetWindowLong(hwndDlg, GWL_EXSTYLE) & ~WS_EX_LAYERED; ws |= dat->flags & SMF_USETRANSPARENCY ? WS_EX_LAYERED : 0; SetWindowLong(hwndDlg , GWL_EXSTYLE , ws); if (dat->flags & SMF_USETRANSPARENCY) { pSetLayeredWindowAttributes(hwndDlg, RGB(255,255,255), (BYTE)(255-g_dat->inactiveAlpha), LWA_ALPHA); // RedrawWindow(hwndDlg, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN); } } if (LOWORD(wParam) != WA_ACTIVE) break; case WM_MOUSEACTIVATE: if (KillTimer(hwndDlg, TIMERID_FLASHWND)) { FlashWindow(hwndDlg, FALSE); dat->nFlash = 0; } ws = GetWindowLong(hwndDlg, GWL_EXSTYLE) & ~WS_EX_LAYERED; ws |= dat->flags & SMF_USETRANSPARENCY ? WS_EX_LAYERED : 0; SetWindowLong(hwndDlg , GWL_EXSTYLE , ws); if (dat->flags & SMF_USETRANSPARENCY) { pSetLayeredWindowAttributes(hwndDlg, RGB(255,255,255), (BYTE)(255-g_dat->activeAlpha), LWA_ALPHA); // RedrawWindow(hwndDlg, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN); } SendMessage(dat->hwndActive, WM_ACTIVATE, WA_ACTIVE, 0); break; case WM_LBUTTONDOWN: dat->mouseLBDown = 1; GetCursorPos(&dat->mouseLBDownPos); SetCapture(hwndDlg); break; case WM_LBUTTONUP: dat->mouseLBDown = 0; ReleaseCapture(); break; case WM_MOUSEMOVE: if (dat->mouseLBDown) { POINT pt; RECT rc; GetCursorPos(&pt); GetWindowRect(hwndDlg, &rc); SetWindowPos(hwndDlg, 0, rc.left - (dat->mouseLBDownPos.x - pt.x), rc.top - (dat->mouseLBDownPos.y - pt.y), 0, 0, SWP_NOZORDER | SWP_NOSIZE); dat->mouseLBDownPos = pt; } break; case WM_DESTROY: { g_dat->hParent = NULL; SetWindowLong(hwndDlg, GWL_USERDATA, 0); WindowList_Remove(g_dat->hParentWindowList, hwndDlg); if (dat->children!=NULL) free (dat->children); free(dat->tabCtrlDat); free(dat); if (dat->flags & SMF_USETABS) { WINDOWPLACEMENT wp = { 0 }; wp.length = sizeof(wp); GetWindowPlacement(hwndDlg, &wp); DBWriteContactSettingDword(NULL, SRMMMOD, "x", wp.rcNormalPosition.left); DBWriteContactSettingDword(NULL, SRMMMOD, "y", wp.rcNormalPosition.top); DBWriteContactSettingDword(NULL, SRMMMOD, "width", wp.rcNormalPosition.right - wp.rcNormalPosition.left); DBWriteContactSettingDword(NULL, SRMMMOD, "height", wp.rcNormalPosition.bottom - wp.rcNormalPosition.top); } else { WINDOWPLACEMENT wp = { 0 }; HANDLE hContact; if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SAVEPERCONTACT, SRMSGDEFSET_SAVEPERCONTACT)) hContact = dat->hContact; else hContact = NULL; wp.length = sizeof(wp); GetWindowPlacement(hwndDlg, &wp); if (!dat->windowWasCascaded) { DBWriteContactSettingDword(hContact, SRMMMOD, "x", wp.rcNormalPosition.left); DBWriteContactSettingDword(hContact, SRMMMOD, "y", wp.rcNormalPosition.top); } DBWriteContactSettingDword(hContact, SRMMMOD, "width", wp.rcNormalPosition.right - wp.rcNormalPosition.left); DBWriteContactSettingDword(hContact, SRMMMOD, "height", wp.rcNormalPosition.bottom - wp.rcNormalPosition.top); } } break; case DM_ERRORDECIDED: break; case DM_STARTFLASHING: if (GetActiveWindow() != hwndDlg || GetForegroundWindow() != hwndDlg) { dat->nFlash = 0; SetTimer(hwndDlg, TIMERID_FLASHWND, TIMEOUT_FLASHWND, NULL); } break; case DM_REMOVECHILD: { RemoveChild(dat, (HWND) lParam); if (dat->childrenCount == 0) { DestroyWindow(hwndDlg); } else { } } return TRUE; case DM_ADDCHILD: { struct MessageWindowData * mdat = (struct MessageWindowData *) lParam; AddChild(dat, mdat); } return TRUE; case DM_ACTIVATECHILD: if((HWND) lParam != dat->hwndActive) { ActivateChild(dat, (HWND) lParam); } return TRUE; case DM_ACTIVATEPREV: ActivatePrevChild(dat, (HWND) lParam); return TRUE; case DM_ACTIVATENEXT: ActivateNextChild(dat, (HWND) lParam); return TRUE; case DM_SENDMESSAGE: { int i; for (i=0;i<dat->childrenCount;i++) { SendMessage(dat->children[i], DM_SENDMESSAGE, wParam, lParam); } } break; case DM_OPTIONSAPPLIED: { RECT rc; dat->flags = g_dat->flags; if (!(dat->flags & SMF_SHOWSTATUSBAR)) { ShowWindow(dat->hwndStatus, SW_HIDE); } else { ShowWindow(dat->hwndStatus, SW_SHOW); } ws = GetWindowLong(hwndDlg, GWL_STYLE) & ~(WS_CAPTION); if (dat->flags & SMF_SHOWTITLEBAR) { ws |= WS_CAPTION; } SetWindowLong(hwndDlg, GWL_STYLE, ws); ws = GetWindowLong(hwndDlg, GWL_EXSTYLE)& ~WS_EX_LAYERED; ws |= dat->flags & SMF_USETRANSPARENCY ? WS_EX_LAYERED : 0; SetWindowLong(hwndDlg , GWL_EXSTYLE , ws); if (dat->flags & SMF_USETRANSPARENCY) { pSetLayeredWindowAttributes(hwndDlg, RGB(255,255,255), (BYTE)(255-g_dat->inactiveAlpha), LWA_ALPHA); // RedrawWindow(hwndDlg, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN); } ws = GetWindowLong(dat->hwndTabs, GWL_STYLE) & ~(TCS_BOTTOM); if (dat->flags & SMF_TABSATBOTTOM) { ws |= TCS_BOTTOM; } SetWindowLong(dat->hwndTabs, GWL_STYLE, ws); RedrawWindow(dat->hwndTabs, NULL, NULL, RDW_INVALIDATE); GetWindowRect(hwndDlg, &rc); SetWindowPos(hwndDlg, 0, 0, 0, rc.right - rc.left, rc.bottom - rc.top, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOSENDCHANGING); SendMessage(hwndDlg, WM_SIZE, 0, 0); //RedrawWindow(hwndDlg, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN); break; } case DM_UPDATETITLE: { struct MessageWindowData * mdat = (struct MessageWindowData *) lParam; TCITEM tci; int tabId; char newtitle[256], oldtitle[256]; char *szStatus, *contactName, *pszNewTitleEnd; TCHAR *tContactName; if (mdat && mdat->hwnd == dat->hwndActive) { pszNewTitleEnd = "Message Session"; if (mdat->hContact) { if (mdat->szProto) { CONTACTINFO ci; char buf[128]; int statusIcon = DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_STATUSICON, SRMSGDEFSET_STATUSICON); buf[0] = 0; mdat->wStatus = DBGetContactSettingWord(mdat->hContact, mdat->szProto, "Status", ID_STATUS_OFFLINE); contactName = (char *) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM) mdat->hContact, 0); ZeroMemory(&ci, sizeof(ci)); ci.cbSize = sizeof(ci); ci.hContact = mdat->hContact; ci.szProto = mdat->szProto; ci.dwFlag = CNF_UNIQUEID; if (!CallService(MS_CONTACT_GETCONTACTINFO, 0, (LPARAM) & ci)) { switch (ci.type) { case CNFT_ASCIIZ: mir_snprintf(buf, sizeof(buf), "%s", ci.pszVal); miranda_sys_free(ci.pszVal); break; case CNFT_DWORD: mir_snprintf(buf, sizeof(buf), "%u", ci.dVal); break; } } szStatus = (char *) CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, mdat->szProto == NULL ? ID_STATUS_OFFLINE : DBGetContactSettingWord(mdat->hContact, mdat->szProto, "Status", ID_STATUS_OFFLINE), 0); if (statusIcon) mir_snprintf(newtitle, sizeof(newtitle), "%s - %s", contactName, Translate(pszNewTitleEnd)); else mir_snprintf(newtitle, sizeof(newtitle), "%s (%s): %s", contactName, szStatus, Translate(pszNewTitleEnd)); } } else lstrcpynA(newtitle, pszNewTitleEnd, sizeof(newtitle)); GetWindowTextA(hwndDlg, oldtitle, sizeof(oldtitle)); if (lstrcmpA(newtitle, oldtitle)) { //swt() flickers even if the title hasn't actually changed SetWindowTextA(hwndDlg, newtitle); //SendMessage(hwndDlg, WM_SIZE, 0, 0); } } tabId = GetTabFromHWND(dat, mdat->hwnd); tContactName = GetTabName(mdat->hContact); tci.mask = TCIF_TEXT; tci.pszText = tContactName; TabCtrl_SetItem(dat->hwndTabs, tabId, &tci); free(tContactName); break; } case DM_UPDATEWINICON: { struct MessageWindowData * mdat = (struct MessageWindowData *) lParam; if (mdat) { if (mdat->szProto) { int i, icoIdx = 0; WORD wStatus; wStatus = DBGetContactSettingWord(mdat->hContact, mdat->szProto, "Status", ID_STATUS_OFFLINE); if (mdat->hwnd == dat->hwndActive) { if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_STATUSICON, SRMSGDEFSET_STATUSICON)) { if (mdat->showTyping && (dat->flags&SMF_SHOWTYPINGWIN)) { SendMessage(hwndDlg, WM_SETICON, (WPARAM) ICON_BIG, (LPARAM) g_dat->hIcons[SMF_ICON_TYPING]); } else if (mdat->showUnread && (GetActiveWindow() != hwndDlg || GetForegroundWindow() != hwndDlg)) { SendMessage(hwndDlg, WM_SETICON, (WPARAM) ICON_BIG, (LPARAM) LoadSkinnedIcon(SKINICON_EVENT_MESSAGE)); } else { SendMessage(hwndDlg, WM_SETICON, (WPARAM) ICON_BIG, (LPARAM) LoadSkinnedProtoIcon(mdat->szProto, wStatus)); } } else { SendMessage(hwndDlg, WM_SETICON, (WPARAM) ICON_BIG, (LPARAM) LoadSkinnedIcon(SKINICON_EVENT_MESSAGE)); } } icoIdx = 0; for (i = 0; i < g_dat->protoNum; i++) { if (!strcmp(g_dat->protoNames[i], mdat->szProto)) { icoIdx = wStatus - ID_STATUS_OFFLINE + (ID_STATUS_OUTTOLUNCH - ID_STATUS_OFFLINE + 1) * (i +1) + 2; break; } } if (mdat->hwnd != dat->hwndActive) { if (mdat->showTyping) { icoIdx = 1; } else if (mdat->showUnread & 1) { icoIdx = 0; } } i = GetTabFromHWND(dat, mdat->hwnd); if (i>=0) { TCITEM tci; tci.mask = TCIF_IMAGE; tci.iImage = icoIdx; TabCtrl_SetItem(dat->hwndTabs, i, &tci); } } } break; } case DM_UPDATESTATUSBAR: break; case DM_SWITCHSTATUSBAR: dat->flags ^= SMF_SHOWSTATUSBAR; if (!(dat->flags & SMF_SHOWSTATUSBAR)) { ShowWindow(dat->hwndStatus, SW_HIDE); } else { ShowWindow(dat->hwndStatus, SW_SHOW); } SendMessage(hwndDlg, WM_SIZE, 0, 0); break; case DM_SWITCHTOOLBAR: { int i; dat->flags ^= SMF_SHOWBTNS; for (i=0;i<dat->childrenCount;i++) { SendMessage(dat->children[i], DM_SWITCHTOOLBAR, 0, 0); } SendMessage(hwndDlg, WM_SIZE, 0, 0); } break; case DM_SWITCHTITLEBAR: { RECT rc; dat->flags ^= SMF_SHOWTITLEBAR; ws = GetWindowLong(hwndDlg, GWL_STYLE) & ~(WS_CAPTION); if (dat->flags & SMF_SHOWTITLEBAR) { ws |= WS_CAPTION; } SetWindowLong(hwndDlg, GWL_STYLE, ws); GetWindowRect(hwndDlg, &rc); SetWindowPos(hwndDlg, 0, 0, 0, rc.right - rc.left, rc.bottom - rc.top, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOSENDCHANGING); // SendMessage(hwndDlg, WM_SIZE, 0, 0); RedrawWindow(hwndDlg, NULL, NULL, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN); } break; case DM_CASCADENEWWINDOW: if ((HWND) wParam == hwndDlg) break; { RECT rcThis, rcNew; GetWindowRect(hwndDlg, &rcThis); GetWindowRect((HWND) wParam, &rcNew); if (abs(rcThis.left - rcNew.left) < 3 && abs(rcThis.top - rcNew.top) < 3) { int offset = GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYFRAME); SetWindowPos((HWND) wParam, 0, rcNew.left + offset, rcNew.top + offset, 0, 0, SWP_NOZORDER | SWP_NOSIZE); *(int *) lParam = 1; } } break; //case DM_MESSAGESENDING: // dat->messagesInProgress += wParam ? -1 : 1; // if (dat->messagesInProgress < 0) dat->messagesInProgress = 0; // break; } return FALSE; }
BOOL CALLBACK ContainerDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { ChatContainer *container; container = (ChatContainer *) GetWindowLong(hwndDlg, GWL_USERDATA); if (container==NULL && msg!=WM_INITDIALOG) return FALSE; switch (msg) { case WM_INITDIALOG: SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM) muccIcon[MUCC_IDI_CHAT]); container = (ChatContainer *) lParam; container->setHWND(hwndDlg); TabCtrl_SetImageList(GetDlgItem(hwndDlg, IDC_TABS), hImageList); SetWindowLong(hwndDlg, GWL_USERDATA, (LONG) container); ShowWindow(hwndDlg, SW_SHOW); SetEvent(container->getEvent()); return TRUE; case WM_GETMINMAXINFO: MINMAXINFO *mmi; RECT rcChild, rcWindow; mmi = (MINMAXINFO *) lParam; GetWindowRect(hwndDlg, &rcWindow); container->getChildWindowRect(&rcChild); mmi->ptMinTrackSize.x = 380; mmi->ptMinTrackSize.y = 130 + (rcWindow.bottom - rcWindow.top) - (rcChild.bottom - rcChild.top); return FALSE; case WM_SIZE: if (IsIconic(hwndDlg) || wParam == SIZE_MINIMIZED) break; { RECT rc, rcChild, rcWindow; GetClientRect(hwndDlg, &rc); HWND hwndTabs = GetDlgItem(hwndDlg, IDC_TABS); MoveWindow(hwndTabs, 0, 0, (rc.right - rc.left), (rc.bottom - rc.top) - 0, FALSE); RedrawWindow(hwndTabs, NULL, NULL, RDW_INVALIDATE | RDW_FRAME | RDW_ERASE); container->getChildWindowRect(&rcChild); if ((rcChild.bottom-rcChild.top) < 130 || (rcChild.right-rcChild.left) < 380) { GetWindowRect(hwndDlg, &rcWindow); if ((rcChild.bottom-rcChild.top) < 130) { rcWindow.bottom = rcWindow.top + 130 + (rcWindow.bottom - rcWindow.top) - (rcChild.bottom - rcChild.top); } if ((rcChild.right-rcChild.left) < 380) { rcWindow.right = rcWindow.left + 380; } MoveWindow(hwndDlg, rcWindow.left, rcWindow.top, rcWindow.right - rcWindow.left, rcWindow.bottom - rcWindow.top, TRUE); container->getChildWindowRect(&rcChild); } if (container->getActive()!=NULL) { MoveWindow(container->getActive()->getHWND(), rcChild.left, rcChild.top, rcChild.right-rcChild.left, rcChild.bottom - rcChild.top, TRUE); } } return TRUE; case DM_CREATECHILD: SetWindowLong(hwndDlg, DWL_MSGRESULT, (LONG)CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_GROUPCHAT_LOG), hwndDlg, (DLGPROC) wParam, (LPARAM) lParam)); return TRUE; case DM_ADDCHILD: container->addChild((ChatWindow *) lParam); return TRUE; case DM_REMOVECHILD: container->removeChild((ChatWindow *) lParam); return TRUE; case DM_CHANGECHILDDATA: container->removeChild((ChatWindow *) lParam); return TRUE; case DM_SETUNREAD: container->setUnread((ChatWindow *) lParam, (int)wParam); return TRUE; case DM_FLASHWINDOW: if (GetActiveWindow() != hwndDlg && GetForegroundWindow() != hwndDlg) { container->setFlash(0); SetTimer(hwndDlg, TIMERID_FLASHWND, container->getFlashTimeout(), NULL); } return TRUE; case WM_NOTIFY: { NMHDR* pNMHDR = (NMHDR*) lParam; switch (pNMHDR->code) { case TCN_SELCHANGE: { TCITEM tci = {0}; HWND hwndTabs = GetDlgItem(hwndDlg, IDC_TABS); int iSel = TabCtrl_GetCurSel(hwndTabs); tci.mask = TCIF_PARAM; if (TabCtrl_GetItem(hwndTabs, iSel, &tci)) { ChatWindow * chatWindow = (ChatWindow *) tci.lParam; container->activateChild(chatWindow); } } break; case NM_CLICK: { FILETIME ft; TCHITTESTINFO thinfo; int tabId; HWND hwndTabs = GetDlgItem(hwndDlg, IDC_TABS); GetSystemTimeAsFileTime(&ft); GetCursorPos(&thinfo.pt); ScreenToClient(hwndTabs, &thinfo.pt); tabId = TabCtrl_HitTest(hwndTabs, &thinfo); if (tabId != -1 && tabId == container->lastClickTab && (ft.dwLowDateTime - container->lastClickTime) < (GetDoubleClickTime() * 10000)) { SendMessage(container->getChildFromTab(tabId)->getHWND(), WM_CLOSE, 0, 0); container->lastClickTab = -1; } else { container->lastClickTab = tabId; } container->lastClickTime = ft.dwLowDateTime; } break; } } break; case WM_ACTIVATE: if (LOWORD(wParam) != WA_ACTIVE) break; case WM_MOUSEACTIVATE: if (KillTimer(hwndDlg, TIMERID_FLASHWND)) { FlashWindow(hwndDlg, FALSE); } /* if (container->getActive()!=NULL) { container->setUnread(container->getActive(), 0); SendMessage(container->getActive()->getHWND(), WM_ACTIVATE, WA_ACTIVE, 0); }*/ break; case WM_CLOSE: EndDialog(hwndDlg, 0); return FALSE; case WM_TIMER: if (wParam == TIMERID_FLASHWND) { if ((container->getFlash() > container->getFlashMax()) || (GetActiveWindow() == hwndDlg) || (GetForegroundWindow() == hwndDlg)) { KillTimer(hwndDlg, TIMERID_FLASHWND); FlashWindow(hwndDlg, FALSE); } else if (container->getFlash() < container->getFlashMax()) { FlashWindow(hwndDlg, TRUE); container->setFlash(container->getFlash()+1); } } break; case WM_DESTROY: SetWindowLong(hwndDlg, GWL_USERDATA, 0); delete container; return TRUE; } return FALSE; }
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { static uint32_t lanLastPing = 0; static HFONT _hFont = 0; switch (message) { case WM_CREATE: { HFONT hFont = 0; NONCLIENTMETRICS ncm = { sizeof(ncm) }; if (SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0)) { hFont = CreateFontIndirect(&ncm.lfMessageFont); _hFont = hFont; } if (!hFont) hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT); RECT rcClient; GetClientRect(hWnd, &rcClient); g_hWndListViewServers = CreateWindow(WC_LISTVIEW, nullptr, WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | LVS_REPORT | LVS_SHOWSELALWAYS | LVS_AUTOARRANGE | LVS_OWNERDATA, 1, 21, rcClient.right - UI_PLAYERLIST_WIDTH - 4, rcClient.bottom - UI_SERVERINFO_HEIGHT - 21 - 2, hWnd, nullptr, g_hInst, nullptr); if (g_hWndListViewServers) { SetWindowTheme(g_hWndListViewServers, L"Explorer", nullptr); ListView_SetExtendedListViewStyle(g_hWndListViewServers, LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER); LVCOLUMN lvc; lvc.mask = LVCF_WIDTH; lvc.cx = 30; ListView_InsertColumn(g_hWndListViewServers, 0, &lvc); lvc.mask = LVCF_WIDTH | LVCF_TEXT; lvc.cx = 240; lvc.pszText = LoadStr(L"Server Name", IDS_SERVERNAME); ListView_InsertColumn(g_hWndListViewServers, 1, &lvc); lvc.cx = 60; lvc.pszText = LoadStr(L"Ping", IDS_PING); ListView_InsertColumn(g_hWndListViewServers, 2, &lvc); lvc.cx = 80; lvc.pszText = LoadStr(L"Players", IDS_PLAYERS); ListView_InsertColumn(g_hWndListViewServers, 3, &lvc); lvc.cx = 70; lvc.pszText = LoadStr(L"Version", IDS_VERSION); ListView_InsertColumn(g_hWndListViewServers, 4, &lvc); lvc.cx = 120; lvc.pszText = LoadStr(L"Gamemode", IDS_GAMEMODE); ListView_InsertColumn(g_hWndListViewServers, 5, &lvc); lvc.cx = 100; lvc.pszText = LoadStr(L"Map Name", IDS_MAPNAME); ListView_InsertColumn(g_hWndListViewServers, 6, &lvc); } g_hWndListViewHistory = CreateWindow(WC_LISTVIEW, nullptr, WS_CHILD | WS_CLIPSIBLINGS | LVS_REPORT | LVS_SHOWSELALWAYS | LVS_AUTOARRANGE | LVS_OWNERDATA, 1, 21, rcClient.right - UI_PLAYERLIST_WIDTH - 4, rcClient.bottom - UI_SERVERINFO_HEIGHT - 21 - 2, hWnd, nullptr, g_hInst, nullptr); if (g_hWndListViewHistory) { SetWindowTheme(g_hWndListViewHistory, L"Explorer", nullptr); ListView_SetExtendedListViewStyle(g_hWndListViewHistory, LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER); LVCOLUMN lvc; lvc.mask = LVCF_WIDTH; lvc.cx = 30; ListView_InsertColumn(g_hWndListViewHistory, 0, &lvc); lvc.mask = LVCF_WIDTH | LVCF_TEXT; lvc.cx = 220; lvc.pszText = LoadStr(L"Server Name", IDS_SERVERNAME); ListView_InsertColumn(g_hWndListViewHistory, 1, &lvc); lvc.cx = 60; lvc.pszText = LoadStr(L"Ping", IDS_PING); ListView_InsertColumn(g_hWndListViewHistory, 2, &lvc); lvc.cx = 80; lvc.pszText = LoadStr(L"Players", IDS_PLAYERS); ListView_InsertColumn(g_hWndListViewHistory, 3, &lvc); lvc.cx = 70; lvc.pszText = LoadStr(L"Version", IDS_VERSION); ListView_InsertColumn(g_hWndListViewHistory, 4, &lvc); lvc.cx = 100; lvc.pszText = LoadStr(L"Gamemode", IDS_GAMEMODE); ListView_InsertColumn(g_hWndListViewHistory, 5, &lvc); lvc.cx = 160; lvc.pszText = LoadStr(L"Last Played", IDS_LASTPLAYED); ListView_InsertColumn(g_hWndListViewHistory, 6, &lvc); } g_hWndTab = CreateWindow(WC_TABCONTROL, nullptr, WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE, 0, 0, rcClient.right - UI_PLAYERLIST_WIDTH, rcClient.bottom - UI_SERVERINFO_HEIGHT, hWnd, nullptr, g_hInst, nullptr); if (g_hWndTab) { SetWindowFont(g_hWndTab, hFont, FALSE); HIMAGELIST hTabIml = ImageList_Create(16, 16, ILC_COLOR32, 0, 0); if (hTabIml) { for (int i = IDI_FAVORITE; i <= IDI_HISTORY; ++i) ImageList_AddIcon(hTabIml, LoadIcon(g_hInst, MAKEINTRESOURCE(i))); TabCtrl_SetImageList(g_hWndTab, hTabIml); } TCITEM tie; tie.mask = TCIF_TEXT | TCIF_IMAGE; tie.iImage = 0; tie.pszText = LoadStr(L"Favorites", IDS_FAVORITES); TabCtrl_InsertItem(g_hWndTab, 0, &tie); tie.iImage = 1; tie.pszText = LoadStr(L"Internet", IDS_INTERNET); TabCtrl_InsertItem(g_hWndTab, 1, &tie); tie.iImage = 1; tie.pszText = LoadStr(L"Official", IDS_OFFICIAL); TabCtrl_InsertItem(g_hWndTab, 2, &tie); tie.iImage = 2; tie.pszText = LoadStr(L"Lan", IDS_LAN); TabCtrl_InsertItem(g_hWndTab, 3, &tie); tie.iImage = 3; tie.pszText = LoadStr(L"History", IDS_HISTORY); TabCtrl_InsertItem(g_hWndTab, 4, &tie); } g_hWndListViewPlayers = CreateWindowEx(0, WC_LISTVIEW, nullptr, WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | LVS_REPORT | LVS_SHOWSELALWAYS | LVS_NOCOLUMNHEADER | LVS_SINGLESEL | LVS_OWNERDATA, rcClient.right - UI_PLAYERLIST_WIDTH + 1, 18, UI_PLAYERLIST_WIDTH - 2, rcClient.bottom - UI_SERVERINFO_HEIGHT - 18 - 2, hWnd, nullptr, g_hInst, nullptr); if (g_hWndListViewPlayers) { SetWindowTheme(g_hWndListViewPlayers, L"Explorer", nullptr); ListView_SetExtendedListViewStyle(g_hWndListViewPlayers, LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER); LVCOLUMN lvc; lvc.mask = LVCF_WIDTH; lvc.cx = UI_PLAYERLIST_WIDTH - 2; ListView_InsertColumn(g_hWndListViewPlayers, 0, &lvc); } g_hWndGroupBox1 = CreateWindow(WC_BUTTON, LoadStr(L"Players", IDS_PLAYERSLIST), WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | BS_GROUPBOX, rcClient.right - UI_PLAYERLIST_WIDTH, 0, UI_PLAYERLIST_WIDTH, rcClient.bottom - UI_SERVERINFO_HEIGHT, hWnd, nullptr, g_hInst, nullptr); if (g_hWndGroupBox1) { SetWindowFont(g_hWndGroupBox1, hFont, FALSE); } g_hWndGroupBox2 = CreateWindow(WC_BUTTON, LoadStr(L"Server Info", IDS_SERVERINFO), WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | BS_GROUPBOX, 0, rcClient.bottom - UI_SERVERINFO_HEIGHT, rcClient.right, 118, hWnd, nullptr, g_hInst, nullptr); if (g_hWndGroupBox2) { SetWindowFont(g_hWndGroupBox2, hFont, FALSE); int y = 18; #define LINE_GAP 20 HWND hStatic = CreateWindow(WC_STATIC, LoadStr(L"Server Name:", IDS_SERVERNAME_), WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | SS_RIGHT, 10, y, 100, 16, g_hWndGroupBox2, nullptr, g_hInst, nullptr); if (hStatic) SetWindowFont(hStatic, hFont, FALSE); HWND hEdit = CreateWindow(WC_EDIT, nullptr, WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | ES_READONLY, 112, y, 300, 16, g_hWndGroupBox2, (HMENU)1001, g_hInst, nullptr); if (hEdit) SetWindowFont(hEdit, hFont, FALSE); y += LINE_GAP; hStatic = CreateWindow(WC_STATIC, LoadStr(L"Server IP:", IDS_SERVERIP), WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | SS_RIGHT, 10, y, 100, 16, g_hWndGroupBox2, nullptr, g_hInst, nullptr); if (hStatic) SetWindowFont(hStatic, hFont, FALSE); hEdit = CreateWindow(WC_EDIT, nullptr, WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | ES_READONLY, 112, y, 300, 16, g_hWndGroupBox2, (HMENU)1002, g_hInst, nullptr); if (hEdit) SetWindowFont(hEdit, hFont, FALSE); y += LINE_GAP; hStatic = CreateWindow(WC_STATIC, LoadStr(L"Server Players:", IDS_SERVERPLAYERS), WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | SS_RIGHT, 10, y, 100, 16, g_hWndGroupBox2, nullptr, g_hInst, nullptr); if (hStatic) SetWindowFont(hStatic, hFont, FALSE); hEdit = CreateWindow(WC_EDIT, nullptr, WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | ES_READONLY, 112, y, 300, 16, g_hWndGroupBox2, (HMENU)1003, g_hInst, nullptr); if (hEdit) SetWindowFont(hEdit, hFont, FALSE); y += LINE_GAP; hStatic = CreateWindow(WC_STATIC, LoadStr(L"Server Ping:", IDS_SERVERPING), WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | SS_RIGHT, 10, y, 100, 16, g_hWndGroupBox2, nullptr, g_hInst, nullptr); if (hStatic) SetWindowFont(hStatic, hFont, FALSE); hEdit = CreateWindow(WC_EDIT, nullptr, WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | ES_READONLY, 112, y, 300, 16, g_hWndGroupBox2, (HMENU)1004, g_hInst, nullptr); if (hEdit) SetWindowFont(hEdit, hFont, FALSE); y += LINE_GAP; hStatic = CreateWindow(WC_STATIC, LoadStr(L"Server Gamemode:", IDS_SERVERGAMEMODE), WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | SS_RIGHT, 10, y, 100, 16, g_hWndGroupBox2, nullptr, g_hInst, nullptr); if (hStatic) SetWindowFont(hStatic, hFont, FALSE); hEdit = CreateWindow(WC_EDIT, nullptr, WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | ES_READONLY, 112, y, 300, 16, g_hWndGroupBox2, (HMENU)1005, g_hInst, nullptr); if (hEdit) SetWindowFont(hEdit, hFont, FALSE); } g_hWndStatusBar = CreateWindow(STATUSCLASSNAME, nullptr, WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | SBARS_SIZEGRIP, 0, 0, 0, 0, hWnd, nullptr, g_hInst, nullptr); do { g_UDPSocket = socket(AF_INET, SOCK_DGRAM, 0); if (g_UDPSocket == INVALID_SOCKET) break; uint32_t timeout = 2000; setsockopt(g_UDPSocket, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout)); struct sockaddr_in bindaddr = { AF_INET }; if (bind(g_UDPSocket, (sockaddr *)&bindaddr, 16) != NO_ERROR) { closesocket(g_UDPSocket); break; } if (WSAAsyncSelect(g_UDPSocket, hWnd, WM_SOCKET, FD_READ) == SOCKET_ERROR) { closesocket(g_UDPSocket); break; } return 0; } while (0); } break; case WM_COMMAND: { int wmId = LOWORD(wParam); switch (wmId) { case IDM_TOOLS_SETTINGS: ShowSettings(); break; case IDM_ABOUT: DialogBox(g_hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); break; case IDM_EXIT: DestroyWindow(hWnd); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } } break; case WM_NOTIFY: { switch (((LPNMHDR)lParam)->code) { case TCN_SELCHANGE: { g_currentTab = TabCtrl_GetCurSel(((LPNMHDR)lParam)->hwndFrom); switch (g_currentTab) { case 0: // Favorites case 1: // Internet case 2: // Official case 3: // Lan ListView_DeleteAllItems(g_hWndListViewServers); ListView_DeleteAllItems(g_hWndListViewPlayers); g_serversList.clear(); ShowWindow(g_hWndListViewServers, SW_SHOW); ShowWindow(g_hWndListViewHistory, SW_HIDE); UpdateWindow(g_hWndListViewServers); if (g_currentTab == 1 || g_currentTab == 2) { HWND hDialog = CreateDialog(g_hInst, MAKEINTRESOURCEW(IDD_LOADING), hWnd, nullptr); SetWindowPos(hDialog, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); UpdateWindow(hDialog); if (g_serversMasterList) { delete g_serversMasterList; g_serversMasterList = nullptr; } std::string data; data.reserve(2048); const char *url; if (g_currentTab == 1) url = (g_browserSettings.masterlistURL + "/servers").c_str(); else url = (g_browserSettings.masterlistURL + "/official").c_str(); CURLcode curlRet = CurlRequset(url, data, "VCMP/0.4"); if (curlRet == CURLE_OK) { serverMasterList serversList; if (ParseJson(data.data(), serversList)) { for (auto it = serversList.begin(); it != serversList.end(); ++it) { SendQuery(it->address, 'i'); it->lastPing = GetTickCount(); } g_serversMasterList = new serverMasterList(serversList); } else { MessageBox(hWnd, LoadStr(L"Can't parse master list data.", IDS_MASTERLISTDATA), LoadStr(L"Error", IDS_ERROR), MB_ICONWARNING); } } else { wchar_t message[512]; swprintf_s(message, LoadStr(L"Can't get information from master list.\n%hs", IDS_MASTERLISTFAILED), curl_easy_strerror(curlRet)); MessageBox(hWnd, message, LoadStr(L"Error", IDS_ERROR), MB_ICONWARNING); } DestroyWindow(hDialog); } else if (g_currentTab == 3) { BOOL broadcast = TRUE; setsockopt(g_UDPSocket, SOL_SOCKET, SO_BROADCAST, (char *)&broadcast, sizeof(broadcast)); for (uint16_t port = 8000; port <= 8200; ++port) { serverAddress address = { INADDR_BROADCAST, port }; SendQuery(address, 'i'); } broadcast = FALSE; setsockopt(g_UDPSocket, SOL_SOCKET, SO_BROADCAST, (char *)&broadcast, sizeof(broadcast)); lanLastPing = GetTickCount(); } break; case 4: // History ShowWindow(g_hWndListViewHistory, SW_SHOW); ShowWindow(g_hWndListViewServers, SW_HIDE); break; } } break; case LVN_GETDISPINFO: { LPNMLVDISPINFOW di = (LPNMLVDISPINFOW)lParam; if (di->hdr.hwndFrom == g_hWndListViewServers) { size_t i = di->item.iItem; if (g_serversList.size() > i) { if (di->item.iSubItem == 0 && di->item.mask & LVIF_IMAGE) di->item.iImage = 0; if (di->item.mask & LVIF_TEXT) { switch (di->item.iSubItem) { case 0: // Icon break; case 1: // Server Name if (di->item.cchTextMax > 0 && di->item.pszText) { MultiByteToWideChar(CP_ACP, 0, g_serversList[i].info.serverName.c_str(), -1, di->item.pszText, di->item.cchTextMax); } break; case 2: // Ping { uint32_t ping = g_serversList[i].lastRecv - g_serversList[i].lastPing[1]; _itow_s(ping, di->item.pszText, di->item.cchTextMax, 10); } break; case 3: // Players swprintf_s(di->item.pszText, di->item.cchTextMax, L"%hu/%hu", g_serversList[i].info.players, g_serversList[i].info.maxPlayers); break; case 4: // Version { MultiByteToWideChar(CP_ACP, 0, g_serversList[i].info.versionName, -1, di->item.pszText, di->item.cchTextMax); } break; case 5: // Gamemode { MultiByteToWideChar(CP_ACP, 0, g_serversList[i].info.gameMode.c_str(), -1, di->item.pszText, di->item.cchTextMax); } break; case 6: // Map name { MultiByteToWideChar(CP_ACP, 0, g_serversList[i].info.mapName.c_str(), -1, di->item.pszText, di->item.cchTextMax); } break; } } } } else if (di->hdr.hwndFrom == g_hWndListViewHistory) // FIXME { } else if (di->hdr.hwndFrom == g_hWndListViewPlayers) { size_t i = ListView_GetSelectionMark(g_hWndListViewServers); if (g_serversList.size() > i) { serverPlayers &players = g_serversList[i].players; size_t j = di->item.iItem; if (players.size() > j) { if (di->item.mask & LVIF_TEXT) { MultiByteToWideChar(CP_ACP, 0, players[j].name, -1, di->item.pszText, di->item.cchTextMax); } } } } } break; case NM_CUSTOMDRAW: { LPNMLVCUSTOMDRAW nmcd = (LPNMLVCUSTOMDRAW)lParam; if (nmcd->nmcd.hdr.hwndFrom == g_hWndListViewServers) { switch (nmcd->nmcd.dwDrawStage) { case CDDS_PREPAINT: return CDRF_NOTIFYITEMDRAW; case CDDS_ITEMPREPAINT: { COLORREF crText; size_t i = nmcd->nmcd.dwItemSpec; if (g_serversList.size() > i && g_serversList[i].isOfficial) crText = g_browserSettings.officialColor; else crText = 0; nmcd->clrText = crText; return CDRF_DODEFAULT; } } } } break; case LVN_ITEMCHANGED: { LPNMITEMACTIVATE nmitem = (LPNMITEMACTIVATE)lParam; if (nmitem->hdr.hwndFrom == g_hWndListViewServers) { size_t i = nmitem->iItem; if (i != -1 && g_serversList.size() > i) { if (g_serversList[i].info.players == 0) ListView_DeleteAllItems(g_hWndListViewPlayers); std::wstring wstr; ConvertCharset(g_serversList[i].info.serverName.c_str(), wstr); SetDlgItemText(g_hWndGroupBox2, 1001, wstr.c_str()); // Server Name wchar_t ipstr[22]; char *ip = (char *)&(g_serversList[i].address.ip); swprintf_s(ipstr, L"%hhu.%hhu.%hhu.%hhu:%hu", ip[0], ip[1], ip[2], ip[3], g_serversList[i].address.port); SetDlgItemText(g_hWndGroupBox2, 1002, ipstr); // Server IP wchar_t playersstr[12]; swprintf_s(playersstr, L"%hu/%hu", g_serversList[i].info.players, g_serversList[i].info.maxPlayers); SetDlgItemText(g_hWndGroupBox2, 1003, playersstr); // Server Players wchar_t pingsstr[12]; uint32_t ping = g_serversList[i].lastRecv - g_serversList[i].lastPing[1]; _itow_s(ping, pingsstr, 10); SetDlgItemText(g_hWndGroupBox2, 1004, pingsstr); // Server Ping ConvertCharset(g_serversList[i].info.gameMode.c_str(), wstr); SetDlgItemText(g_hWndGroupBox2, 1005, wstr.c_str()); // Server Gamemode SendQuery(g_serversList[i].address, 'i'); SendQuery(g_serversList[i].address, 'c'); g_serversList[i].lastPing[0] = GetTickCount(); } else { ListView_DeleteAllItems(g_hWndListViewPlayers); for (int i = 1001; i <= 1005; ++i) SetDlgItemText(g_hWndGroupBox2, i, nullptr); } } } break; case LVN_ITEMACTIVATE: { LPNMITEMACTIVATE nmia = (LPNMITEMACTIVATE)lParam; if (nmia->hdr.hwndFrom == g_hWndListViewServers) { size_t i = nmia->iItem; if (i != -1 && g_serversList.size() > i) { char ipstr[16]; char *ip = (char *)&(g_serversList[i].address.ip); snprintf(ipstr, sizeof(ipstr), "%hhu.%hhu.%hhu.%hhu", ip[0], ip[1], ip[2], ip[3]); char vcmpDll[MAX_PATH]; snprintf(vcmpDll, sizeof(vcmpDll), "%ls%s\\vcmp-game.dll", g_exePath, g_serversList[i].info.versionName); LaunchVCMP(ipstr, g_serversList[i].address.port, g_browserSettings.playerName, nullptr, g_browserSettings.gamePath, vcmpDll); } } } break; } } break; case WM_SIZE: { int clientWidth = GET_X_LPARAM(lParam), clientHeight = GET_Y_LPARAM(lParam); SetWindowPos(g_hWndTab, 0, 0, 0, clientWidth - UI_PLAYERLIST_WIDTH, clientHeight - UI_SERVERINFO_HEIGHT, SWP_NOZORDER); SetWindowPos(g_hWndListViewServers, 0, 1, 21, clientWidth - UI_PLAYERLIST_WIDTH - 4, clientHeight - UI_SERVERINFO_HEIGHT - 21 - 2, SWP_NOZORDER); SetWindowPos(g_hWndListViewHistory, 0, 1, 21, clientWidth - UI_PLAYERLIST_WIDTH - 4, clientHeight - UI_SERVERINFO_HEIGHT - 21 - 2, SWP_NOZORDER); SetWindowPos(g_hWndGroupBox1, 0, clientWidth - UI_PLAYERLIST_WIDTH, 0, UI_PLAYERLIST_WIDTH, clientHeight - UI_SERVERINFO_HEIGHT, SWP_NOZORDER); SetWindowPos(g_hWndListViewPlayers, 0, clientWidth - UI_PLAYERLIST_WIDTH + 1, 18, UI_PLAYERLIST_WIDTH - 2, clientHeight - UI_SERVERINFO_HEIGHT - 18 - 2, SWP_NOZORDER); SetWindowPos(g_hWndGroupBox2, 0, 0, clientHeight - UI_SERVERINFO_HEIGHT, clientWidth, 118, SWP_NOZORDER); SendMessage(g_hWndStatusBar, WM_SIZE, 0, 0); } break; case WM_GETMINMAXINFO: ((LPMINMAXINFO)lParam)->ptMinTrackSize = { 750, 500 }; break; case WM_DESTROY: if (_hFont) DeleteObject(_hFont); PostQuitMessage(0); break; case WM_SOCKET: { if (WSAGETSELECTEVENT(lParam) == FD_READ) { char *recvBuf = (char *)calloc(1024, sizeof(char)); if (recvBuf) { struct sockaddr_in recvAddr; int addrLen = sizeof(recvAddr); int recvLen = recvfrom(g_UDPSocket, recvBuf, 1024, 0, (sockaddr *)&recvAddr, &addrLen); if (recvLen != -1 && recvLen >= 11) { if (recvLen > 1024) recvLen = 1024; if (*(int *)recvBuf == 0x3430504D) // MP04 { char opcode = recvBuf[10]; if (opcode == 'i' || opcode == 'c') { uint32_t ip = recvAddr.sin_addr.s_addr; uint16_t port = ntohs(recvAddr.sin_port); bool found = false; serverMasterListInfo masterInfo; if (g_currentTab == 1 || g_currentTab == 2) { for (auto it = g_serversMasterList->begin(); it != g_serversMasterList->end(); ++it) { if (it->address.ip == ip && it->address.port == port) { found = true; masterInfo = *it; break; } } } else if (g_currentTab == 3) // Lan { found = true; masterInfo.address = { ip, port }; masterInfo.isOfficial = false; masterInfo.lastPing = lanLastPing; } if (found) { switch (opcode) { case 'i': { serverInfo info; if (GetServerInfo(recvBuf, recvLen, info)) { bool inList = false; for (auto it = g_serversList.begin(); it != g_serversList.end(); ++it) { if (it->address.ip == ip && it->address.port == port) { inList = true; it->lastRecv = GetTickCount(); it->lastPing[1] = it->lastPing[0]; it->info = info; auto i = it - g_serversList.begin(); ListView_Update(g_hWndListViewServers, i); break; } } if (!inList) { serverAllInfo allInfo; allInfo.address = masterInfo.address; allInfo.info = info; allInfo.isOfficial = masterInfo.isOfficial; allInfo.lastPing[0] = masterInfo.lastPing; allInfo.lastPing[1] = masterInfo.lastPing; allInfo.lastRecv = GetTickCount(); g_serversList.push_back(allInfo); LVITEM lvi = { 0 }; ListView_InsertItem(g_hWndListViewServers, &lvi); } } } break; case 'c': { serverPlayers players; if (GetServerPlayers(recvBuf, recvLen, players)) { for (auto it = g_serversList.begin(); it != g_serversList.end(); ++it) { if (it->address.ip == ip && it->address.port == port) { it->lastRecv = GetTickCount(); it->lastPing[1] = it->lastPing[0]; it->players = players; auto i = it - g_serversList.begin(); ListView_SetItemCount(g_hWndListViewPlayers, players.size()); break; } } } } break; } } } } } free(recvBuf); } } } break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; }
//--------------------------------------------------------------------------- //WM_INITDIALOG: void TfrmMain::wmInitdialog(WPARAM wParam, LPARAM lParam) { HWND hCtrl; //Taskbar and Window icon SendMessage(m_hWnd, WM_SETICON, ICON_BIG, (LPARAM)IcoLib_GetIcon(ICO_PLUG_SSWINDOW1, true)); SendMessage(m_hWnd, WM_SETICON, ICON_SMALL, (LPARAM)IcoLib_GetIcon(ICO_PLUG_SSWINDOW2)); LPTSTR pt = mir_a2t(__PLUGIN_NAME); SetWindowText(m_hWnd, pt); mir_freeAndNil(pt); // Headerbar pt = mir_tstrdup((LPTSTR)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)m_hContact, (LPARAM)GCDNF_TCHAR)); if (pt && (m_hContact != 0)) { LPTSTR lptString = NULL; mir_tcsadd(lptString , TranslateT("Send screenshot to\n")); mir_tcsadd(lptString , pt); SetDlgItemText(m_hWnd, IDC_HEADERBAR, lptString); mir_free(lptString); } mir_freeAndNil(pt); SendMessage(GetDlgItem(m_hWnd, IDC_HEADERBAR), WM_SETICON, 0, (WPARAM)IcoLib_GetIcon(ICO_PLUG_SSWINDOW1, true)); //Timed controls CheckDlgButton(m_hWnd,ID_chkTimed, m_opt_chkTimed ? BST_CHECKED : BST_UNCHECKED); SetDlgItemInt (m_hWnd,ID_edtTimed, (UINT)m_opt_edtTimed, FALSE); SendDlgItemMessage(m_hWnd, ID_upTimed, UDM_SETRANGE, 0, (LPARAM)MAKELONG(250, 1)); chkTimedClick(); //enable disable Timed controls //create Image list for tab control if(m_himlTab == 0) { //m_himlTab = ImageList_Create(16, 16, PluginConfig.m_bIsXP ? ILC_COLOR32 | ILC_MASK : ILC_COLOR8 | ILC_MASK, 2, 0); m_himlTab = ImageList_Create(16, 16, ILC_COLOR32 | ILC_MASK, 2, 0); ImageList_AddIcon(m_himlTab, IcoLib_GetIcon(ICO_PLUG_SSWINDOW2)); ImageList_AddIcon(m_himlTab, IcoLib_GetIcon(ICO_PLUG_SSWINDOW2)); } //create the tab control. { TAB_INFO itab; RECT rcClient, rcTab; m_hwndTab = GetDlgItem(m_hWnd, IDC_CAPTURETAB); TabCtrl_SetItemExtra(m_hwndTab, sizeof(TAB_INFO) - sizeof(TCITEMHEADER)); ZeroMemory(&itab, sizeof(itab)); itab.hwndMain = m_hWnd; itab.hwndTab = m_hwndTab; GetWindowRect(m_hwndTab, &rcTab); GetWindowRect(m_hWnd, &rcClient); TabCtrl_SetImageList(m_hwndTab, m_himlTab); // Add a tab for each of the three child dialog boxes. itab.tcih.mask = TCIF_PARAM|TCIF_TEXT|TCIF_IMAGE; itab.tcih.pszText = TranslateT("Window"); itab.tcih.iImage = 0; itab.hwndTabPage = CreateDialog(hInst,MAKEINTRESOURCE(IDD_UMain_CaptureWindow), m_hWnd,DlgProc_CaptureWindow); TabCtrl_InsertItem(m_hwndTab, 0, &itab); MoveWindow(itab.hwndTabPage, (rcTab.left - rcClient.left)+2, (rcTab.top - rcClient.top), (rcTab.right - rcTab.left) - 2*5, (rcTab.bottom - rcTab.top) - 2*20, TRUE); ShowWindow(itab.hwndTabPage, SW_HIDE); CheckDlgButton(itab.hwndTabPage, ID_chkClientArea, m_opt_chkClientArea ? BST_CHECKED : BST_UNCHECKED); itab.tcih.pszText = TranslateT("Desktop"); itab.tcih.iImage = 1; itab.hwndTabPage = CreateDialog(hInst,MAKEINTRESOURCE(IDD_UMain_CaptureDesktop), m_hWnd, DlgProc_CaptureDesktop); TabCtrl_InsertItem(m_hwndTab, 1, &itab); MoveWindow(itab.hwndTabPage, (rcTab.left - rcClient.left)+2, (rcTab.top - rcClient.top), (rcTab.right - rcTab.left) - 2*5, (rcTab.bottom - rcTab.top) - 2*20, TRUE); ShowWindow(itab.hwndTabPage, SW_HIDE); hCtrl = GetDlgItem(itab.hwndTabPage, ID_edtCaption); ComboBox_ResetContent(hCtrl); ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, TranslateT("<Entire Desktop>")) ,0); ComboBox_SetCurSel (hCtrl,0); if(m_MonitorCount >1) { TCHAR tszTemp[120]; for (size_t i = 0; i < m_MonitorCount; ++i) { mir_sntprintf(tszTemp, SIZEOF(tszTemp),_T("%i. %s%s"), i+1, TranslateT("Monitor"), (m_Monitors[i].dwFlags & MONITORINFOF_PRIMARY) ? TranslateT(" (primary)") : _T("") ); ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, tszTemp) , i+1); } ComboBox_SelectItemData (hCtrl, -1, m_opt_cboxDesktop); //use Workaround for MS bug ComboBox_SelectItemData } PostMessage(m_hWnd, WM_COMMAND, MAKEWPARAM(ID_edtCaption, CBN_SELCHANGE),(LPARAM)hCtrl); //select tab and set m_hwndTabPage TabCtrl_SetCurSel(m_hwndTab, m_opt_tabCapture); ZeroMemory(&itab, sizeof(itab)); itab.tcih.mask = TCIF_PARAM; TabCtrl_GetItem(m_hwndTab,TabCtrl_GetCurSel(m_hwndTab),&itab); ShowWindow(itab.hwndTabPage,SW_SHOW); m_hwndTabPage = itab.hwndTabPage; } //init Format combo box { hCtrl = GetDlgItem(m_hWnd, ID_cboxFormat); ComboBox_ResetContent(hCtrl); ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, _T("PNG")),0); ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, _T("JPG")),1); ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, _T("BMP")),2); ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, _T("TIF")),3); ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, _T("GIF")),4); ComboBox_SelectItemData (hCtrl, -1, m_opt_cboxFormat); //use Workaround for MS bug ComboBox_SelectItemData } //init SendBy combo box { hCtrl = GetDlgItem(m_hWnd, ID_cboxSendBy); ComboBox_ResetContent(hCtrl); ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, TranslateT("<Only save>")) ,SS_JUSTSAVE); if (m_hContact) { ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, TranslateT("File Transfer")),SS_FILESEND); } else if(m_opt_cboxSendBy == SS_FILESEND) { m_opt_cboxSendBy = SS_IMAGESHACK; } ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, TranslateT("E-mail")) ,SS_EMAIL); if (myGlobals.PluginHTTPExist) { ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, _T("HTTP Server")) ,SS_HTTPSERVER); } else if(m_opt_cboxSendBy == SS_HTTPSERVER) { m_opt_cboxSendBy = SS_IMAGESHACK; } if (myGlobals.PluginFTPExist) { ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, TranslateT("FTP File")) ,SS_FTPFILE); } else if(m_opt_cboxSendBy == SS_FTPFILE) { m_opt_cboxSendBy = SS_IMAGESHACK; } ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, TranslateT("ImageShack")) ,(BYTE)SS_IMAGESHACK); ComboBox_SelectItemData (hCtrl, -1, m_opt_cboxSendBy); //use Workaround for MS bug ComboBox_SelectItemData cboxSendByChange(); //enable disable controls } //init footer options CheckDlgButton(m_hWnd,ID_chkOpenAgain, m_opt_chkOpenAgain ? BST_CHECKED : BST_UNCHECKED); if (hCtrl = GetDlgItem(m_hWnd, ID_btnAbout)) { SendDlgItemMessage(m_hWnd, ID_btnAbout, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Information"), MBBF_TCHAR); HICON hIcon = IcoLib_GetIcon(ICO_PLUG_SSHELP); SendMessage(hCtrl, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon); SetWindowText(hCtrl, hIcon ? _T("") : _T("?")); } if (hCtrl = GetDlgItem(m_hWnd, ID_btnExplore)) { SendDlgItemMessage(m_hWnd, ID_btnExplore, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Open Folder"), MBBF_TCHAR); HICON hIcon = IcoLib_GetIcon(ICO_PLUG_SSFOLDERO); SendMessage(hCtrl, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon); SetWindowText(hCtrl, hIcon ? _T("") : _T("...")); } if (hCtrl = GetDlgItem(m_hWnd, ID_btnDesc)) { SendDlgItemMessage(m_hWnd, ID_btnDesc, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Fill description textbox."), MBBF_TCHAR); HICON hIcon = IcoLib_GetIcon(m_opt_btnDesc ? ICO_PLUG_SSDESKON : ICO_PLUG_SSDESKOFF); SendMessage(hCtrl, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon); SetWindowText(hCtrl, hIcon ? _T("") : _T("D")); SendMessage(hCtrl, BM_SETCHECK, m_opt_btnDesc ? BST_CHECKED : BST_UNCHECKED, NULL); } if (hCtrl = GetDlgItem(m_hWnd, ID_btnDeleteAfterSend)) { SendDlgItemMessage(m_hWnd, ID_btnDeleteAfterSend, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Delete after send"), MBBF_TCHAR); HICON hIcon = IcoLib_GetIcon(m_opt_btnDeleteAfterSend ? ICO_PLUG_SSDELON : ICO_PLUG_SSDELOFF); SendMessage(hCtrl, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon); SetWindowText(hCtrl, hIcon ? _T("") : _T("X")); SendMessage(hCtrl, BM_SETCHECK, m_opt_btnDeleteAfterSend ? BST_CHECKED : BST_UNCHECKED, NULL); } if (hCtrl = GetDlgItem(m_hWnd, ID_btnCapture)) { SendDlgItemMessage(m_hWnd, ID_btnCapture, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Capture"), MBBF_TCHAR); HICON hIcon = IcoLib_GetIcon(ICO_PLUG_OK); SendMessage(hCtrl, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon); SetWindowText(hCtrl, TranslateT("&Capture")); SendMessage(hCtrl, BUTTONSETDEFAULT, (WPARAM)1, NULL); } // CheckDlgButton(m_hWnd,ID_chkEditor, m_opt_chkEditor ? BST_CHECKED : BST_UNCHECKED); TranslateDialogDefault(m_hWnd); }
LRESULT CALLBACK PropsTabWndWndProc(HWND hwnd, UINT iMessage, WPARAM wParam, LPARAM lParam) { static int selected, sizingbottom; static HIMAGELIST tabIml; static int ilProps, ilToolbox; RECT r; TC_ITEM tie; NMHDR *h; DRAWITEMSTRUCT *dr; HFONT font; HBITMAP hbmp; HDC hMemDC; PAINTSTRUCT paint; HDC dc; switch (iMessage) { case WM_SYSCOMMAND: if (wParam == SC_CLOSE) { PostMessage(hwnd, WM_CLOSE, 0, 0); return 0; } break; case WM_NOTIFY: h = (NMHDR*)lParam; switch (h->code) { case TCN_SELCHANGE: switch (selected = TabCtrl_GetCurSel(hwndPropsTabCtrl)) { case 0: ShowWindow(hwndToolbox, SW_HIDE) ; ShowWindow(hwndProps, SW_SHOW) ; break; case 1: ShowWindow(hwndProps, SW_HIDE) ; ShowWindow(hwndToolbox, SW_SHOW) ; break; } } break; case WM_SETTEXT: return SendMessage(hwndPropsTabCtrl, iMessage, wParam, lParam); case WM_DRAWITEM: dr = (DRAWITEMSTRUCT*)lParam; hMemDC = CreateCompatibleDC(dr->hDC); hbmp = SelectObject(hMemDC, *bitmaps[dr->itemID]); BitBlt(dr->hDC, dr->rcItem.left + 2, dr->rcItem.bottom - 18, 16, 16, hMemDC, 0, 0, SRCCOPY); font = SelectObject(dr->hDC, font); TextOut(dr->hDC, dr->rcItem.left + 18, dr->rcItem.bottom - 16, nameTags[dr->itemID], strlen(nameTags[dr->itemID])); font = SelectObject(dr->hDC, font); SelectObject(dr->hDC, hbmp); DeleteDC(hMemDC); break; case WM_CREATE: hwndPropsTab = hwnd; GetClientRect(hwnd, &r); hwndPropsTabCtrl = CreateWindow(WC_TABCONTROL, 0, WS_CHILD + WS_CLIPSIBLINGS + WS_VISIBLE + TCS_FLATBUTTONS /*+ TCS_OWNERDRAWFIXED */ + TCS_FOCUSNEVER /*+ TCS_FIXEDWIDTH*/ + TCS_BOTTOM, r.left, r.top, r.right - r.left, r.bottom - r.top, hwnd, 0, hInstance, 0); ApplyDialogFont(hwndPropsTabCtrl); propsBitMap = LoadImage(hInstance, "ID_PROPSBMP", IMAGE_BITMAP,0,0,LR_DEFAULTSIZE | LR_LOADMAP3DCOLORS); toolsBitMap = LoadImage(hInstance, "ID_TOOLBOXBMP", IMAGE_BITMAP,0,0,LR_DEFAULTSIZE | LR_LOADMAP3DCOLORS); tabIml = ImageList_Create(16, 16, ILC_COLOR32, 1, 0); ilProps = ImageList_Add(tabIml, propsBitMap, 0); ilToolbox = ImageList_Add(tabIml, toolsBitMap, 0); TabCtrl_SetImageList(hwndPropsTabCtrl, tabIml); CreatePropsWindow(); CreateCtlTbWindow(); tie.mask = TCIF_TEXT | TCIF_IMAGE; tie.iImage = ilProps; tie.pszText = nameTags[0]; TabCtrl_InsertItem(hwndPropsTabCtrl, 0, &tie); tie.mask = TCIF_TEXT | TCIF_IMAGE ; tie.iImage = ilToolbox ; tie.pszText = nameTags[1] ; TabCtrl_InsertItem(hwndPropsTabCtrl,1, &tie) ; ShowWindow(hwndToolbox,SW_HIDE) ; return 0; case WM_COMMAND: break; case WM_SELERRWINDOW: { NMHDR xx; memset(&xx, 0, sizeof(xx)); xx.code = TCN_SELCHANGE; TabCtrl_SetCurSel(hwndPropsTabCtrl, lParam); SendMessage(hwnd, WM_NOTIFY, 0, (LPARAM)&xx); } break; case WM_PAINT: dc = BeginPaint(hwnd, &paint); EndPaint(hwnd, &paint); break; case WM_DESTROY: DestroyWindow(hwndToolbox) ; DestroyWindow(hwndProps); DestroyWindow(hwndPropsTabCtrl); DeleteObject(propsBitMap); DeleteObject(toolsBitMap); hwndPropsTab = 0; break; case WM_SIZE: r.right = LOWORD(lParam); r.bottom = HIWORD(lParam); r.left = r.top = 0; MoveWindow(hwndPropsTabCtrl, r.left, r.top, r.right - r.left, r.bottom - r.top, 1); GetPropsTabRect(&r); MoveWindow(hwndProps, r.left, r.top, r.right - r.left, r.bottom - r.top, 1); MoveWindow( hwndToolbox,r.left,r.top,r.right-r.left,r.bottom-r.top,TRUE) ; break; case WM_CLOSE: break; } return DefWindowProc(hwnd, iMessage, wParam, lParam); }