static LRESULT CALLBACK PluginListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { if (msg == WM_LBUTTONDOWN) { LVHITTESTINFO hi; hi.pt.x = LOWORD(lParam); hi.pt.y = HIWORD(lParam); ListView_SubItemHitTest(hwnd, &hi); if (hi.iSubItem == 1) { LVITEM lvi = {0}; lvi.mask = LVIF_IMAGE | LVIF_PARAM | LVIF_GROUPID; lvi.stateMask = -1; lvi.iItem = hi.iItem; if (ListView_GetItem(hwnd, &lvi) && lvi.iGroupId == 1) { FILEINFO *info = (FILEINFO *)lvi.lParam; TCHAR tszFileName[MAX_PATH]; _tcscpy(tszFileName, _tcsrchr(info->tszNewName, L'\\') + 1); TCHAR *p = _tcschr(tszFileName, L'.'); *p = 0; TCHAR link[MAX_PATH]; mir_sntprintf(link, MAX_PATH, _T("http://miranda-ng.org/p/%s"), tszFileName); CallService(MS_UTILS_OPENURL, OUF_TCHAR, (LPARAM) link); } } } return CallWindowProc(oldWndProc, hwnd, msg, wParam, lParam); }
static LRESULT CALLBACK PluginListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { if (msg == WM_LBUTTONDOWN) { LVHITTESTINFO hi; hi.pt.x = LOWORD(lParam); hi.pt.y = HIWORD(lParam); ListView_SubItemHitTest(hwnd, &hi); if ((hi.iSubItem == 0) && (hi.flags & LVHT_ONITEMICON)) { LVITEM lvi = {0}; lvi.mask = LVIF_IMAGE | LVIF_PARAM | LVIF_GROUPID; lvi.stateMask = -1; lvi.iItem = hi.iItem; if (ListView_GetItem(hwnd, &lvi) && lvi.iGroupId == 1) { FILEINFO *info = (FILEINFO *)lvi.lParam; TCHAR tszFileName[MAX_PATH]; _tcscpy(tszFileName, _tcsrchr(info->tszNewName, L'\\') + 1); TCHAR *p = _tcschr(tszFileName, L'.'); *p = 0; TCHAR link[MAX_PATH]; mir_sntprintf(link, _countof(link), PLUGIN_INFO_URL, tszFileName); Utils_OpenUrlT(link); } } } return CallWindowProc(oldWndProc, hwnd, msg, wParam, lParam); }
static int IsOverEmail(HWND hwndDlg,TCHAR* szEmail,int cchEmail) { RECT rc; HWND hwndEmails; TCHAR szText[256]; HDC hdc; SIZE textSize; LVHITTESTINFO hti; hwndEmails=GetDlgItem(hwndDlg,IDC_EMAILS); GetCursorPos(&hti.pt); ScreenToClient(hwndEmails,&hti.pt); GetClientRect(hwndEmails,&rc); if(!PtInRect(&rc,hti.pt)) return 0; if(ListView_SubItemHitTest(hwndEmails,&hti)==-1) return 0; if(hti.iSubItem!=1) return 0; if(!(hti.flags&LVHT_ONITEMLABEL)) return 0; ListView_GetSubItemRect(hwndEmails,hti.iItem,1,LVIR_LABEL,&rc); szText[0] = 0; ListView_GetItemText(hwndEmails,hti.iItem,1,szText,SIZEOF(szText)); hdc=GetDC(hwndEmails); SelectObject(hdc,hEmailFont); GetTextExtentPoint32(hdc,szText,lstrlen(szText),&textSize); ReleaseDC(hwndEmails,hdc); if(hti.pt.x<rc.left+textSize.cx) { if(szEmail && cchEmail) lstrcpyn(szEmail,szText,cchEmail); return 1; } return 0; }
// --------------------------------------------------------------------------------- LRESULT APIENTRY historyListWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { extern HISTORY history; switch(msg) { case WM_CHAR: case WM_KEYDOWN: case WM_KEYUP: case WM_KILLFOCUS: return 0; case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK: { if (GetFocus() != hWnd) SetFocus(hWnd); // perform hit test LVHITTESTINFO info; info.pt.x = GET_X_LPARAM(lParam); info.pt.y = GET_Y_LPARAM(lParam); ListView_SubItemHitTest(hWnd, (LPARAM)&info); history.handleSingleClick(info.iItem); return 0; } case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK: { if (GetFocus() != hWnd) SetFocus(hWnd); playback.handleMiddleButtonClick(); return 0; } case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK: if (GetFocus() != hWnd) SetFocus(hWnd); return 0; case WM_MOUSEWHEEL: { if (!history.isCursorOverHistoryList()) return SendMessage(pianoRoll.hwndList, msg, wParam, lParam); break; } case WM_MOUSEWHEEL_RESENT: { // this is message from Piano Roll // it means that cursor is currently over History List, and user scrolls the wheel (although focus may be on some other window) // ensure that wParam's low-order word is 0 (so fwKeys = 0) CallWindowProc(hwndHistoryList_oldWndProc, hWnd, WM_MOUSEWHEEL, wParam & ~(LOWORD(-1)), lParam); return 0; } case WM_MOUSEACTIVATE: if (GetFocus() != hWnd) SetFocus(hWnd); break; } return CallWindowProc(hwndHistoryList_oldWndProc, hWnd, msg, wParam, lParam); }
TableView::ItemPos TableViewImpl::getItemPos(Point point) const { LVHITTESTINFO info; info.pt = convertPoint(point); info.flags = LVHT_ONITEM; info.iItem = -1; ListView_SubItemHitTest(hWnd,&info); return TableView::ItemPos{info.iSubItem,info.iItem}; }
static LRESULT ScoreLineView_OnDoubleClick(HWND hParent, HWND hwnd) { LVHITTESTINFO hti; hti.flags = LVHT_ONITEMLABEL; ::GetCursorPos(&hti.pt); ::ScreenToClient(hwnd, &hti.pt); // ヒット if (ListView_SubItemHitTest(hwnd, &hti) != -1) { // キャラ部分のクリック if (hti.iItem >= 0 && hti.iItem < TH135AddrGetCharCount()) { // 勝ちか負け if (hti.iSubItem == 2 || hti.iSubItem == 3) { BOOL trDirLeft = reinterpret_cast<BOOL>(GetProp(hParent, PROP_TRDIRLEFT)); SCORELINE_ITEM item; SYSTEMTIME loctime; GetLocalTime(&loctime); SystemTimeToFileTime(&loctime, (LPFILETIME)&item.timestamp); LVITEM lvitem; lvitem.mask = LVIF_PARAM; lvitem.iItem = hti.iItem; lvitem.iSubItem = 0; ListView_GetItem(hwnd, &lvitem); if (trDirLeft) { item.p1name[0] = 0; item.p1id = reinterpret_cast<int>(::GetProp(hParent, PROP_PID)); item.p1win = hti.iSubItem == 2 ? 2 : 0; item.p2name[0] = 0; item.p2id = LVPARAMFIELD(lvitem.lParam).charId; item.p2win = hti.iSubItem == 3 ? 2 : 0; } else { item.p1name[0] = 0; item.p1id = LVPARAMFIELD(lvitem.lParam).charId; item.p1win = hti.iSubItem == 2 ? 2 : 0; item.p2name[0] = 0; item.p2id = reinterpret_cast<int>(::GetProp(hParent, PROP_PID)); item.p2win = hti.iSubItem == 3 ? 2 : 0; } ScoreLine_Enter(); bool failed = !ScoreLine_Append(&item); ScoreLine_Leave(failed); if (!failed) { Memento_Append(MEMENTO_CMD_APPEND, &item); ScoreLineQIBSpecDialog_Reflesh(hParent); ::PostMessage(GetParent(hParent), UM_UPDATESCORELINE, 0, 0); } } } } return TRUE; }
void CSortListCtrl::CellHitTest(const CPoint& pt, int& nRow, int& nCol) const { nRow = -1; nCol = -1; LVHITTESTINFO lvhti = {0}; lvhti.pt = pt; nRow = ListView_SubItemHitTest(m_hWnd, &lvhti); // SubItemHitTest is non-const nCol = lvhti.iSubItem; if (!(lvhti.flags & LVHT_ONITEMLABEL)) nRow = -1; }
static LRESULT ScoreLineView_OnRDoubleClick(HWND hParent, HWND hwnd) { LVHITTESTINFO hti; hti.flags = LVHT_ONITEMLABEL; ::GetCursorPos(&hti.pt); ::ScreenToClient(hwnd, &hti.pt); // ヒット if (ListView_SubItemHitTest(hwnd, &hti) != -1) { // 勝ちか負け if (hti.iSubItem == 2 || hti.iSubItem == 3) { LVITEM lvitem; lvitem.mask = LVIF_PARAM; lvitem.iItem = hti.iItem; lvitem.iSubItem = 0; ListView_GetItem(hwnd, &lvitem); SCORELINE_FILTER_DESC *fltCustom = reinterpret_cast<SCORELINE_FILTER_DESC *>(GetProp(hParent, PROP_FILTER)); if (!fltCustom) { ::MessageBox(NULL, _T("戦績の変更に失敗しました"), NULL, MB_OK); return FALSE; } SCORELINE_FILTER_DESC filterDesc = *fltCustom; filterDesc.mask |= SCORELINE_FILTER__P2ID; filterDesc.p2id = lvitem.lParam; if (hti.iSubItem == 2) { filterDesc.mask |= SCORELINE_FILTER__P1WIN; filterDesc.p1win = 2; } else { filterDesc.mask |= SCORELINE_FILTER__P2WIN; filterDesc.p2win = 2; } SCORELINE_ITEM item; if (ScoreLine_QueryTrackRecordTop(filterDesc, item)) { ScoreLine_Enter(); bool failed = !ScoreLine_Remove(item.timestamp); ScoreLine_Leave(failed); if (!failed) { Memento_Append(MEMENTO_CMD_REMOVE, &item); ScoreLineQIBSpecDialog_Reflesh(hParent); ::PostMessage(GetParent(hParent), UM_UPDATESCORELINE, 0, 0); } } } } return TRUE; }
void CSHListCtrl::OnLButtonDblClk(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default LVHITTESTINFO ht; ht.pt = point; // Test for which subitem was clicked. // Use macro since this is new and not in MFC. int rval = ListView_SubItemHitTest( m_hWnd, &ht ); // Store the old column number and set the new column value. int oldsubitem = m_CurSubItem; m_CurSubItem = IndexToOrder( ht.iSubItem ); CHeaderCtrl* pHeader = (CHeaderCtrl*)GetDlgItem(0); // Make the column fully visible. // We have to take into account that the columns may be reordered MakeColumnVisible( Header_OrderToIndex( pHeader->m_hWnd, m_CurSubItem ) ); // Store old state of the item. int state = GetItemState( ht.iItem, LVIS_FOCUSED ); // Bail if the state from before was not focused or the // user has not already clicked on this cell. if( !state || m_CurSubItem == -1 || oldsubitem != m_CurSubItem ) return; // Send Notification to parent of ListView ctrl CString str; str = GetItemText( ht.iItem, ht.iSubItem ); LV_DISPINFO dispinfo; dispinfo.hdr.hwndFrom = m_hWnd; dispinfo.hdr.idFrom = GetDlgCtrlID(); dispinfo.hdr.code = LVN_BEGINLABELEDIT; dispinfo.item.mask = LVIF_TEXT; dispinfo.item.iItem = ht.iItem; dispinfo.item.iSubItem = ht.iSubItem; dispinfo.item.pszText = (LPTSTR)((LPCTSTR)str); dispinfo.item.cchTextMax = str.GetLength(); GetParent()->SendMessage( WM_NOTIFY, GetDlgCtrlID(), (LPARAM)&dispinfo ); // My code end here CListCtrl::OnLButtonDblClk(nFlags, point); }
LRESULT CInfoPanel::OnSetCursor(WORD wHitTest, WORD wMouseMsg) { if(wHitTest!=HTCLIENT) return 0; LVHITTESTINFO ht = {0}; DWORD dwPos = GetMessagePos(); ht.pt.x=GET_X_LPARAM(dwPos); ht.pt.y=GET_Y_LPARAM(dwPos); ScreenToClient(m_hListWnd, &ht.pt); ListView_SubItemHitTest(m_hListWnd, &ht); if(ht.iItem>=0 && ht.iSubItem==0) { SetCursor(LoadCursor(NULL,IDC_HAND)); return TRUE; } return FALSE; }
INT_PTR CSubTooltipListCtrl::OnToolHitTest(CPoint point, TOOLINFO * pTI) const { if (pProvider == NULL) return -1; LVHITTESTINFO lvhitTestInfo; lvhitTestInfo.pt = point; int nItem = ListView_SubItemHitTest( this->m_hWnd, &lvhitTestInfo); int nSubItem = lvhitTestInfo.iSubItem; UINT nFlags = lvhitTestInfo.flags; //nFlags is 0 if the SubItemHitTest fails //Therefore, 0 & <anything> will equal false if (nFlags & LVHT_ONITEM) { //If it did fall on a list item, //and it was also hit one of the //item specific sub-areas we wish to show tool tips for //Get the client (area occupied by this control RECT rcClient; GetClientRect( &rcClient ); //Fill in the TOOLINFO structure pTI->hwnd = m_hWnd; pTI->uId = (UINT)((nItem<<10)+(nSubItem&0x3ff)+1); pTI->lpszText = LPSTR_TEXTCALLBACK; pTI->rect = rcClient; return pTI->uId; //By returning a unique value per listItem, //we ensure that when the mouse moves over another list item, //the tooltip will change } else { //Otherwise, we aren't interested, so let the message propagate return -1; } }
/// Function name : onArgumentPage_ContextMenu // Description : Display the GamePage or GameString editing popup menu // // SCRIPT_DOCUMENT* pDocument : [in] Language document data // HWND hCtrl : [in] Window handle of the control sending the message // CONST POINT ptCursor : [in] Cursor position // // Return Value : TRUE // BOOL onArgumentPage_ContextMenu(SCRIPT_DOCUMENT* pDocument, HWND hCtrl, CONST POINT ptCursor) { CUSTOM_MENU* pCustomMenu; // Custom Popup menu // [ARGUMENT LIST] Display the editing context menu if (GetDlgCtrlID(hCtrl) == IDC_ARGUMENTS_LIST) { // [TRACK] CONSOLE_ACTION(); // Prepare INT iIndex = ListView_GetSelected(hCtrl), iCount = (INT)getScriptFileArgumentCount(pDocument->pScriptFile); /// Identify the sub-item clicked (if any) if (ListView_GetSelected(hCtrl) != -1) { // Store results in Document pDocument->oItemClick.pt = ptCursor; ScreenToClient(hCtrl, &pDocument->oItemClick.pt); ListView_SubItemHitTest(hCtrl, &pDocument->oItemClick); } else pDocument->oItemClick.iItem = pDocument->oItemClick.iSubItem = -1; /// Create Arguments custom popup menu pCustomMenu = createCustomMenu(TEXT("SCRIPT_MENU"), TRUE, IDM_ARGUMENT_POPUP); // Disable 'Edit' and 'Remove' if user didn't click an existing argument item EnableMenuItem(pCustomMenu->hPopup, IDM_ARGUMENT_EDIT, pDocument->oItemClick.iItem != -1 ? MF_ENABLED : MF_DISABLED); EnableMenuItem(pCustomMenu->hPopup, IDM_ARGUMENT_DELETE, pDocument->oItemClick.iItem != -1 ? MF_ENABLED : MF_DISABLED); // Disable 'Move Up' when index is zero EnableMenuItem(pCustomMenu->hPopup, IDM_ARGUMENT_MOVE_UP, iIndex > 0 && iIndex != -1 ? MF_ENABLED : MF_DISABLED); EnableMenuItem(pCustomMenu->hPopup, IDM_ARGUMENT_MOVE_DOWN, iIndex < iCount-1 && iIndex != -1 ? MF_ENABLED : MF_DISABLED); /// Display context menu TrackPopupMenu(pCustomMenu->hPopup, TPM_TOPALIGN WITH TPM_LEFTALIGN, ptCursor.x, ptCursor.y, NULL, GetParent(hCtrl), NULL); deleteCustomMenu(pCustomMenu); } return TRUE; }
LRESULT CALLBACK StringTableDrawProc(HWND hwnd, UINT iMessage, WPARAM wParam, LPARAM lParam) { static HCURSOR origCurs; RECT r; LPCREATESTRUCT createStruct; struct resRes *stringTableData; LVHITTESTINFO hittest; int i; struct stringTableUndo *undo; switch (iMessage) { case WM_MDIACTIVATE: if ((HWND)lParam == hwnd) { doMaximize(); } break; case WM_SETFOCUS: stringTableData = (struct resRes *)GetWindowLong(hwnd, 0); SetFocus(stringTableData->gd.childWindow); break; case WM_NOTIFY: switch (((LPNMHDR)lParam)->code) { case LVN_GETDISPINFO: { LV_DISPINFO *plvdi = (LV_DISPINFO*)lParam; STRINGS *strings; plvdi->item.mask |= LVIF_TEXT | LVIF_DI_SETITEM; plvdi->item.mask &= ~LVIF_IMAGE; strings = (STRINGS *)plvdi->item.lParam; switch (plvdi->item.iSubItem) { char id[256]; case 1: FormatVersionString(id, strings->string, strings->length);//FIXME id plvdi->item.pszText = id; break; } break; } case LVN_KEYDOWN: { stringTableData = (struct resRes *)GetWindowLong(hwnd, 0); SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(ID_EDIT, CBN_KILLFOCUS), 0); switch (((LPNMLVKEYDOWN)lParam)->wVKey) { case 'S': if (GetKeyState(VK_CONTROL) &0x80000000) { PostMessage(hwnd, WM_COMMAND, IDM_SAVE, 0); return TRUE; } break; case 'Z': if (GetKeyState(VK_CONTROL) &0x80000000) { PostMessage(hwnd, WM_COMMAND, IDM_UNDO, 0); return TRUE; } break; case VK_INSERT: stringTableData->gd.selectedRow = ListView_GetNextItem(stringTableData->gd.childWindow, -1, LVNI_SELECTED); PostMessage(hwnd, WM_COMMAND, IDM_INSERT, 0); return TRUE; case VK_DELETE: stringTableData->gd.selectedRow = ListView_GetNextItem(stringTableData->gd.childWindow, -1, LVNI_SELECTED); PostMessage(hwnd, WM_COMMAND, IDM_DELETE, 0); return TRUE; } } break; case NM_CLICK: { SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(ID_EDIT, CBN_KILLFOCUS), 0); } break; case NM_RCLICK: { POINT pt; stringTableData = (struct resRes *)GetWindowLong(hwnd, 0); GetCursorPos(&hittest.pt); pt = hittest.pt; ScreenToClient(stringTableData->gd.childWindow, &hittest.pt); if (ListView_HitTest(stringTableData->gd.childWindow, &hittest) < 0) { hittest.iItem = ListView_GetItemCount(stringTableData->gd.childWindow); hittest.iSubItem = 0; } { HMENU menu, popup; SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(ID_EDIT, CBN_KILLFOCUS), 0); menu = LoadMenuGeneric(hInstance, "RESSTRINGSMENU"); stringTableData = (struct resRes *)GetWindowLong(hwnd, 0); stringTableData->gd.selectedRow = hittest.iItem; stringTableData->gd.selectedColumn = hittest.iSubItem; popup = GetSubMenu(menu, 0); InsertBitmapsInMenu(popup); TrackPopupMenuEx(popup, TPM_TOPALIGN | TPM_LEFTALIGN | TPM_LEFTBUTTON, pt.x, pt.y, hwnd, NULL); DestroyMenu(menu); } return 1; } break; case NM_DBLCLK: stringTableData = (struct resRes *)GetWindowLong(hwnd, 0); GetCursorPos(&hittest.pt); ScreenToClient(stringTableData->gd.childWindow, &hittest.pt); if (ListView_SubItemHitTest(stringTableData->gd.childWindow, &hittest) >= 0) { stringTableData = (struct resRes *)GetWindowLong(hwnd, 0); stringTableData->gd.selectedRow = hittest.iItem; stringTableData->gd.selectedColumn = hittest.iSubItem; PostMessage(hwnd, WM_HANDLEDBLCLICK, 0, 0); } break; case NM_SETFOCUS: stringTableData = (struct resRes *)GetWindowLong(hwnd, 0); SetResourceProperties(stringTableData, &accFuncs); break; case NM_KILLFOCUS: // SetResourceProperties(NULL, NULL); break; } break; case WM_HANDLEDBLCLICK: { STRINGS *strings; RECT r; stringTableData = (struct resRes *)GetWindowLong(hwnd, 0); if (stringTableData->gd.editWindow) { DestroyWindow(stringTableData->gd.editWindow); stringTableData->gd.editWindow = NULL; } strings = stringTableData->resource->u.stringtable; i = 0; while (strings && strings->next && i < stringTableData->gd.selectedRow) strings = strings->next, i++; if (strings) { ListView_GetSubItemRect(stringTableData->gd.childWindow, stringTableData->gd.selectedRow, stringTableData->gd.selectedColumn, LVIR_BOUNDS, &r); stringTableData->gd.editWindow = CreateWindow("edit", "", WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS | WS_BORDER, r.left,r.top,r.right-r.left,16, hwnd, (HMENU)ID_EDIT, hInstance, NULL); SetParent(stringTableData->gd.editWindow, stringTableData->gd.childWindow); AccSubclassEditWnd(hwnd, stringTableData->gd.editWindow); switch(stringTableData->gd.selectedColumn) { char buf[256]; case 0: buf[0] = 0; FormatExp(buf, strings->id); SendMessage(stringTableData->gd.editWindow, WM_SETTEXT, 0, (LPARAM)buf); break; case 1: FormatVersionString(buf, strings->string, strings->length); buf[strlen(buf)-1] = 0; SendMessage(stringTableData->gd.editWindow, WM_SETTEXT, 0, (LPARAM)buf+1); break; } SendMessage(stringTableData->gd.editWindow, EM_SETSEL, 0, -1); SetFocus(stringTableData->gd.editWindow); } } break; case WM_TIMER: stringTableData = (struct resRes *)GetWindowLong(hwnd, 0); ListView_Scroll(stringTableData->gd.childWindow, 0, (stringTableData->gd.lvscroll & 1) ? -16 : 16); break; case WM_COMMAND: stringTableData = (struct resRes *)GetWindowLong(hwnd, 0); switch (LOWORD(wParam)) { case ID_EDIT: if (HIWORD(wParam) == CBN_KILLFOCUS || HIWORD(wParam) == EN_KILLFOCUS) { static BOOL inKillFocus; if (stringTableData->gd.editWindow && !inKillFocus) { STRINGS *strings = stringTableData->resource->u.stringtable; i = 0; while (strings && strings->next && i < stringTableData->gd.selectedRow) strings = strings->next,i++; if (strings) { char buf[256]; buf[GetWindowText(stringTableData->gd.editWindow, buf, sizeof(buf)-1)] = 0; StringTableSetChanged(stringTableData, strings); if (stringTableData->gd.selectedColumn == 0) { PropSetIdName(stringTableData, buf, &strings->id, NULL); } else { int len; char *p = ParseVersionString(buf, &len); //FIXME ? strings->length = StringAsciiToWChar(&strings->string, p, len); ResGetStringItemName(strings->id, p); } ListView_DeleteItem(stringTableData->gd.childWindow, stringTableData->gd.selectedRow); PopulateItem(stringTableData->gd.childWindow, strings, stringTableData->gd.selectedRow); } i = 0; inKillFocus = TRUE; DestroyWindow(stringTableData->gd.editWindow); inKillFocus = FALSE; stringTableData->gd.editWindow = NULL; } } break; case IDM_INSERT: StringTableInsert(stringTableData, stringTableData->gd.selectedRow); break; case IDM_DELETE: StringTableDelete(stringTableData, stringTableData->gd.selectedRow); break; case IDM_SAVE: if (stringTableData->resource->changed) { ResSaveCurrent(workArea, stringTableData); } break; case IDM_UNDO: StringTableUndo(hwnd, stringTableData); break; } break; case EM_CANUNDO: stringTableData = (struct resRes *)GetWindowLong(hwnd, 0); return stringTableData->gd.undoData != NULL; case WM_CREATE: GetClientRect(hwnd, &r); createStruct = (LPCREATESTRUCT)lParam; stringTableData = (struct resRes *)((LPMDICREATESTRUCT)(createStruct->lpCreateParams))->lParam; SetWindowLong(hwnd, 0, (long)stringTableData); stringTableData->activeHwnd = hwnd; stringTableData->gd.childWindow = CreateWindowEx(0, WC_LISTVIEW, "", WS_VISIBLE | WS_CHILD | LVS_REPORT | LVS_SINGLESEL, 0, 0, r.right, r.bottom, hwnd, (HMENU)ID_TREEVIEW, hInstance, NULL); SetListViewColumns(hwnd, stringTableData->gd.childWindow); PopulateStrings(hwnd, stringTableData ); break; case WM_CLOSE: SendMessage(hwndSrcTab, TABM_REMOVE, 0, (LPARAM)hwnd); break; case WM_DESTROY: stringTableData = (struct resRes *)GetWindowLong(hwnd, 0); if (stringTableData->gd.editWindow) DestroyWindow(stringTableData->gd.editWindow); stringTableData->gd.editWindow = NULL; undo = stringTableData->gd.undoData; if (undo) stringTableData->gd.cantClearUndo = TRUE; while (undo) { struct stringTableUndo *next = undo->next; free(undo); undo = next; } stringTableData->gd.undoData = NULL; stringTableData->activeHwnd = NULL; break; case WM_SIZE: stringTableData = (struct resRes *)GetWindowLong(hwnd, 0); MoveWindow(stringTableData->gd.childWindow, 0, 0, LOWORD(lParam), HIWORD(lParam), 1); break; default: break; } return DefMDIChildProc(hwnd, iMessage, wParam, lParam); }
static void ModifyProjectDepends(HWND hwnd, BOOL showingBuildInfo, PROJECTITEM *proj, LV_DISPINFO *plvdi) { if (plvdi->hdr.idFrom == IDC_DEPENDS) { NMITEMACTIVATE *nmia; LVHITTESTINFO lvhtti; int row; switch(plvdi->hdr.code) { case LVN_GETDISPINFO: plvdi->item.mask |= LVIF_TEXT | LVIF_DI_SETITEM; plvdi->item.mask &= ~LVIF_STATE; switch (plvdi->item.iSubItem) { PROJECTITEM *temp; case 1: // for dependencies temp = (PROJECTITEM *)plvdi->item.lParam; plvdi->item.pszText = temp->displayName; break; default: plvdi->item.pszText = ""; break; } break; case NM_CLICK: case NM_DBLCLK: nmia = (NMITEMACTIVATE *)plvdi; memset(&lvhtti, 0, sizeof(lvhtti)); lvhtti.pt = nmia->ptAction; row = ListView_SubItemHitTest(GetDlgItem(hwnd, IDC_DEPENDS), &lvhtti); if (row != -1) { LV_ITEM item; PROJECTITEMLIST **list = &proj->depends; PROJECTITEM *depend; memset(&item, 0, sizeof(item)); item.iItem = row; item.iSubItem = 0; item.mask = LVIF_PARAM; ListView_GetItem(GetDlgItem(hwnd, IDC_DEPENDS), &item); depend = (PROJECTITEM *)item.lParam; if (CircularDepends(proj, depend)) { ListView_SetCheckState(GetDlgItem(hwnd, IDC_DEPENDS), row, !ListView_GetCheckState(GetDlgItem(hwnd, IDC_DEPENDS), row)); } else { MarkChanged(workArea, TRUE); if (!ListView_GetCheckState(GetDlgItem(hwnd, IDC_DEPENDS), row)) { // add while (*list) list = &(*list)->next; (*list) = (PROJECTITEMLIST *)calloc(1, sizeof(PROJECTITEMLIST)); (*list)->item = depend; } else { // remove while (*list) { if ((*list)->item == depend) { PROJECTITEMLIST *found = (*list); (*list) = found->next; free(found); break; } list = &(*list)->next; } } } } break; } } }
LRESULT CALLBACK MainDlg(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam) { static HWND grippy=0; static int col=0,dir=0; #ifdef _DEBUG // if(FALSE) // if(message!=0x200&&message!=0x84&&message!=0x20&&message!=WM_ENTERIDLE) if(msg!=WM_MOUSEFIRST&&msg!=WM_NCHITTEST&&msg!=WM_SETCURSOR&&msg!=WM_ENTERIDLE&&msg!=WM_DRAWITEM &&msg!=WM_CTLCOLORBTN&&msg!=WM_CTLCOLOREDIT) //if(msg!=WM_NCHITTEST&&msg!=WM_SETCURSOR&&msg!=WM_ENTERIDLE) { static DWORD tick=0; if((GetTickCount()-tick)>500) printf("--\n"); printf("*"); print_msg(msg,lparam,wparam); tick=GetTickCount(); } #endif switch(msg) { case WM_INITDIALOG: hlistview=CreateWindow(WC_LISTVIEW,"",WS_TABSTOP|WS_CHILD|WS_CLIPSIBLINGS|WS_VISIBLE|LVS_REPORT|LVS_SHOWSELALWAYS, 0,0, 0,0, hwnd, IDC_LIST1, ghinstance, NULL); ListView_SetExtendedListViewStyle(hlistview,LVS_EX_FULLROWSELECT); populate_list(hlistview,TRUE); sort_listview(hlistview,dir,col); grippy=create_grippy(hwnd); PostMessage(hwnd,WM_SIZE,0,0); //dump_main(hwnd); break; case WM_HELP: show_main_help(hwnd,(HELPINFO *)lparam); return TRUE; break; case WM_SIZE: grippy_move(hwnd,grippy); resize_main(hwnd); break; case WM_CONTEXTMENU: break; case WM_NOTIFY: { NMHDR *nmhdr=lparam; if(nmhdr!=0 && nmhdr->idFrom==IDC_LIST1){ LV_HITTESTINFO lvhit={0}; switch(nmhdr->code){ case NM_DBLCLK: GetCursorPos(&lvhit.pt); ScreenToClient(nmhdr->hwndFrom,&lvhit.pt); if(ListView_SubItemHitTest(nmhdr->hwndFrom,&lvhit)>=0) do_regjump(hlistview); break; case NM_RCLICK: case NM_CLICK: GetCursorPos(&lvhit.pt); ScreenToClient(nmhdr->hwndFrom,&lvhit.pt); if(ListView_SubItemHitTest(nmhdr->hwndFrom,&lvhit)>=0){ } printf("item = %i\n",lvhit.iSubItem); break; case LVN_ITEMCHANGED: { } break; case LVN_KEYDOWN: { } break; case LVN_COLUMNCLICK: { NMLISTVIEW *nmlv=lparam; col=nmlv->iSubItem; dir=!dir; sort_listview(hlistview,dir,col); } break; } } } break; case WM_VKEYTOITEM: switch(LOWORD(wparam)){ case '0':case '1':case'2':case'3':case'4':case'5': break; } return -1; break; case WM_CHARTOITEM: switch(wparam){ case 'z': break; case 'x': break; } break; case WM_COMMAND: switch(LOWORD(wparam)){ case IDC_REFRESH: { RECT rect={0}; RECT newrect={0}; int dx,dy,mark; ListView_GetItemRect(hlistview,0,&rect,LVIR_BOUNDS); mark=ListView_GetSelectionMark(hlistview); populate_list(hlistview,FALSE); sort_listview(hlistview,dir,col); ListView_GetItemRect(hlistview,0,&newrect,LVIR_BOUNDS); dx=-rect.left+newrect.left; dy=-rect.top+newrect.top; ListView_Scroll(hlistview,dx,dy); if(mark>=0) ListView_SetItemState(hlistview,mark,LVIS_FOCUSED|LVIS_SELECTED,LVIS_FOCUSED|LVIS_SELECTED); SetFocus(hlistview); } break; case IDC_INFO: do_regjump(hlistview); break; case IDOK: break; case IDCANCEL: DestroyWindow(hwnd); PostQuitMessage(0); return TRUE; break; } break; case WM_QUERYENDSESSION: SetWindowLong(hwnd,DWL_MSGRESULT,TRUE); //ok to end session return TRUE; case WM_ENDSESSION: if(wparam){ SetWindowLong(hwnd,DWL_MSGRESULT,0); DestroyWindow(hwnd); PostQuitMessage(0); return TRUE; } break; case WM_CLOSE: DestroyWindow(hwnd); PostQuitMessage(0); return TRUE; break; } return 0; }
LRESULT CALLBACK BrowseProc(HWND hwnd, UINT iMessage, WPARAM wParam, LPARAM lParam) { static HFONT font; LV_ITEM item; POINT pt; LV_COLUMN lvC; RECT r; int i; LPNMHDR nmh; static LVITEM pressed; switch (iMessage) { case WM_USER+1: { DWINFO info; char *q; memset(&info,0, sizeof(info)); strcpy(info.dwName, browselist[pressed.lParam]->file); q = strrchr(info.dwName, '\\'); if (q) strcpy(info.dwTitle, q + 1); else strcpy(info.dwTitle, info.dwName); info.dwLineNo = TagNewLine(browselist[pressed.lParam]->file, browselist[pressed.lParam]->line); info.logMRU = FALSE; info.newFile = FALSE; CreateDrawWindow(&info, TRUE); break; } case WM_CTLCOLORSTATIC: { return (LRESULT)(HBRUSH)(COLOR_INACTIVECAPTION + 1); } case WM_CTLCOLORBTN: { return (LRESULT)GetStockObject(NULL_BRUSH); } case WM_NOTIFY: nmh = (LPNMHDR)lParam; if (nmh->code == NM_SETFOCUS) { PostMessage(hwndFrame, WM_REDRAWTOOLBAR, 0, 0); SendMessage(GetParent(hwnd), WM_ACTIVATEME, 0, 0); } else if (nmh->code == LVN_GETDISPINFO) { LV_DISPINFO *p = (LV_DISPINFO *)lParam; char name[512] = "", *q; switch (p->item.iSubItem) { case 1: /* id*/ sprintf(name,"%d", p->item.lParam +1); break; case 2: /*name*/ strcpy(name, browselist[p->item.lParam]->name); break; case 3: /* browse */ sprintf(name, "%d", browselist[p->item.lParam]->line); break; case 4: /*file*/ q = strrchr(browselist[p->item.lParam]->file, '\\'); if (!q) q = browselist[p->item.lParam]->file; else q++; strcpy(name, q); break; } if (name[0]) { p->item.mask |= LVIF_TEXT | LVIF_DI_SETITEM; p->item.mask &= ~LVIF_STATE; p->item.pszText = name; } } else if (((LPNMHDR)lParam)->code == NM_DBLCLK) { LVHITTESTINFO hittest; GetCursorPos(&hittest.pt); ScreenToClient(hwndLV, &hittest.pt); if (ListView_SubItemHitTest(hwndLV, &hittest) >= 0) { LVITEM lvitem; lvitem.iItem = hittest.iItem; lvitem.iSubItem = 0; lvitem.mask = LVIF_PARAM; ListView_GetItem(hwndLV, &lvitem); memcpy(&pressed, &lvitem, sizeof(pressed)); SendMessage(hwnd, WM_USER + 1, 0, 0); } } else if (nmh->code == LVN_KEYDOWN) { switch (((LPNMLVKEYDOWN)lParam)->wVKey) { case 'C': if (GetKeyState(VK_CONTROL) &0x80000000) { CopyText(hwnd); } break; case VK_UP: if (curSel > 0) SendMessage(hwnd, WM_USER, curSel-1, 0); break; case VK_DOWN: if (curSel < ListView_GetItemCount(hwndLV) - 1) SendMessage(hwnd, WM_USER, curSel + 1, 0); break; } } break; case WM_COMMAND: switch(wParam) { case IDC_RETURN: GetWindowText(hwndEdit, brsName, sizeof(brsName)); SendMessage(hwndCombo, WM_SAVEHISTORY, 0, 0); CreateUsageList(); return 0; case IDC_ESCAPE: SendMessage(hwndEdit, WM_SETTEXT, 0, (LPARAM)brsName); return 0; default: if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == 300) { displayFull = !displayFull; PostMessage(hwnd, WM_USER, 0, 0); } if (HIWORD(wParam) == CBN_SELENDOK && LOWORD(wParam) == 500) { PostMessage(hwnd, WM_COMMAND, IDC_RETURN, 0); } break; } break; case WM_USER: { int k = 0; char buf[40]; sprintf(buf, "%d Usages", browsecount); SetWindowText(hwndButton, buf); ListView_DeleteAllItems(hwndLV); memset(&item, 0, sizeof(item)); for (i=0; i < browsecount; i++) { if (displayFull || browselist[i]->definition || browselist[i]->declaration) { item.iItem = k++; item.iSubItem = 0; item.mask = LVIF_IMAGE | LVIF_PARAM; item.lParam = i; item.iImage = browselist[i]->definition ? 0 : browselist[i]->declaration ? 1 : 2; ListView_InsertItem(hwndLV, &item); } } } break; case WM_DRAWITEM: { LPDRAWITEMSTRUCT pDis = (LPDRAWITEMSTRUCT)lParam; HDC memdc; char staticText[256]; BOOL state = !! displayFull; int len = SendMessage(pDis->hwndItem, WM_GETTEXT, sizeof(staticText), (LPARAM)staticText); SIZE sz; RECT r; POINT textpos, iconpos; GetClientRect(pDis->hwndItem, &r); GetTextExtentPoint32(pDis->hDC, staticText, len, &sz); SetBkMode(pDis->hDC, TRANSPARENT); iconpos.x = 4; iconpos.y = (r.bottom - r.top - 16)/2; textpos.x = r.right - 4 - sz.cx; textpos.y = (r.bottom - r.top - sz.cy)/2; DrawFrameControl(pDis->hDC, &pDis->rcItem, DFC_BUTTON, DFCS_BUTTONPUSH | (state ? DFCS_PUSHED : 0)); TextOut(pDis->hDC, pDis->rcItem.left+ textpos.x, pDis->rcItem.top+textpos.y, staticText, len); memdc = CreateCompatibleDC(pDis->hDC); SelectObject(memdc, buttonbmp); TransparentBlt(pDis->hDC, pDis->rcItem.left+ iconpos.x, pDis->rcItem.top+iconpos.y, 16, 16, memdc, 0, 0, 16, 16, 0xc0c0c0); DeleteDC(memdc); } return 0; case WM_CREATE: hwndBrowse = hwnd; GetClientRect(hwnd, &r); hwndBackground = CreateWindow("static", "", WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS, 0,0, r.right - r.bottom, BUTTONHEIGHT + 4, hwnd, 0, hInstance, 0); hwndButton = CreateWindow("button", "0 Usages", WS_CHILD | WS_VISIBLE | BS_OWNERDRAW, 2,2,BUTTONWIDTH,BUTTONHEIGHT, hwnd, (HMENU)300, hInstance, 0); ApplyDialogFont(hwndButton); hwndCombo = CreateWindow("COMBOBOX", "", WS_CHILD + WS_CLIPSIBLINGS + WS_BORDER + WS_VISIBLE + CBS_DROPDOWN + CBS_AUTOHSCROLL, BUTTONWIDTH + 10, 4, 200, 100, hwnd, (HMENU)500, hInstance, 0); ApplyDialogFont(hwndCombo); SubClassHistoryCombo(hwndCombo); SendMessage(hwndCombo, WM_SETHISTORY, 0, (LPARAM)varinfohist); pt.x = pt.y = 5; hwndEdit = ChildWindowFromPoint(hwndCombo, pt); oldproc = (WNDPROC)SetWindowLong(hwndEdit, GWL_WNDPROC, (int)EditHook); BringWindowToTop(hwndButton); BringWindowToTop(hwndCombo); font = CreateFontIndirect(&systemDialogFont); SendMessage(hwndErrButton, WM_SETFONT, (WPARAM)font, 0); SendMessage(hwndWarnButton, WM_SETFONT, (WPARAM)font, 0); hwndLV = CreateWindowEx(0, WC_LISTVIEW, "", LVS_REPORT | LVS_SINGLESEL | WS_CHILD | WS_VISIBLE | WS_BORDER, 0,BUTTONHEIGHT + 4,r.right-r.left, r.bottom - r.top-BUTTONHEIGHT-4, hwnd, 0, hInstance, 0); ListView_SetExtendedListViewStyle(hwndLV, LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_DOUBLEBUFFER); ApplyDialogFont(hwndLV); GetWindowRect(hwndLV, &r); lvC.mask = LVCF_WIDTH; lvC.cx = 50; lvC.iSubItem = 0; ListView_InsertColumn(hwndLV, 0, &lvC); lvC.mask = LVCF_WIDTH | LVCF_SUBITEM | LVCF_TEXT; lvC.cx = 50; lvC.iSubItem = 1; lvC.pszText = "Id"; ListView_InsertColumn(hwndLV, 1, &lvC); lvC.mask = LVCF_WIDTH | LVCF_SUBITEM | LVCF_TEXT; lvC.cx = 250; lvC.iSubItem = 2; lvC.pszText = "Name"; ListView_InsertColumn(hwndLV, 2, &lvC); lvC.mask = LVCF_WIDTH | LVCF_SUBITEM | LVCF_TEXT; lvC.cx = 50; lvC.iSubItem = 3; lvC.pszText = "Line"; ListView_InsertColumn(hwndLV, 3, &lvC); lvC.mask = LVCF_WIDTH | LVCF_SUBITEM | LVCF_TEXT; lvC.cx = r.right - r.left - 375; lvC.iSubItem = 4; lvC.pszText = "File"; ListView_InsertColumn(hwndLV, 4, &lvC); ListView_SetImageList(hwndLV, tagImageList, LVSIL_SMALL); break; case WM_RESETHISTORY: SendMessage(hwndCombo, WM_SETHISTORY, 0, (LPARAM)varinfohist); break; case WM_SIZE: r.left = r.top = 0; r.right = LOWORD(lParam); r.bottom = HIWORD(lParam); MoveWindow(hwndLV, r.left, r.top+BUTTONHEIGHT + 4, r.right - r.left, r.bottom - r.top-BUTTONHEIGHT - 4, 1); MoveWindow(hwndBackground, r.left, r.top, r.right - r.left, BUTTONHEIGHT + 4, 1); lvC.mask = LVCF_WIDTH; lvC.cx = r.right - r.left - 375; ListView_SetColumn(hwndLV, 4, &lvC); break; case WM_DESTROY: hwndBrowse = 0; break; case WM_SETFOCUS: break; case WM_KILLFOCUS: break; } return DefWindowProc(hwnd, iMessage, wParam, lParam); }
/** * name: ListSubclassProc * desc: procedure to catch messages for a listview control, to handle tooltips * param: hwnd - handle to the listview control's window * msg - message sent to the control * wParam - message specific parameter * lParam - message specific parameter * return: message specific **/ static INT_PTR CALLBACK ProfileList_SubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { LPLISTCTRL pList; switch (msg) { case WM_KEYDOWN: { INT nCurSel, newSel; LVITEM lvi; switch (wParam) { case VK_F2: nCurSel = ListView_GetSelectionMark(hwnd); if (nCurSel == -1) break; ProfileList_BeginLabelEdit(hwnd, nCurSel, 0); return 0; case VK_F3: nCurSel = ListView_GetSelectionMark(hwnd); if (nCurSel == -1) break; ProfileList_BeginLabelEdit(hwnd, nCurSel, 1); return 0; case VK_UP: case VK_DOWN: lvi.iItem = nCurSel = ListView_GetSelectionMark(hwnd); lvi.iSubItem = 0; // find next valid item to select lvi.mask = LVIF_PARAM; do { if (wParam == VK_UP) lvi.iItem--; else lvi.iItem++; if (lvi.iItem == -1 || !ListView_GetItem(hwnd, &lvi)) { return 0; } } while (!lvi.lParam); ListView_EnsureVisible(hwnd, lvi.iItem, FALSE); newSel = lvi.iItem; lvi.iItem = nCurSel; lvi.mask = LVIF_STATE; lvi.stateMask = LVIS_FOCUSED|LVIS_SELECTED; lvi.state = 0; ListView_SetItem(hwnd, &lvi); lvi.iItem = newSel; lvi.state = LVIS_FOCUSED|LVIS_SELECTED; ListView_SetItem(hwnd, &lvi); ListView_SetSelectionMark(hwnd, lvi.iItem); return 0; } break; } case WM_MOUSEMOVE: if (PtrIsValid(pList = (LPLISTCTRL)GetUserData(hwnd))) { HDC hDC; RECT rchWnd, rcItem; SIZE textSize; LVHITTESTINFO hi; TOOLINFO ti; BOOLEAN bReposition; LPLCITEM pItem; hi.pt.x = GET_X_LPARAM(lParam); hi.pt.y = GET_Y_LPARAM(lParam); ListView_SubItemHitTest(hwnd, &hi); // show tip only if pointer is over an item if (pList->iHotItem != hi.iItem || pList->iHotSubItem != hi.iSubItem) { bReposition = pList->iHotItem != -1 || pList->iHotSubItem != -1; pList->iHotItem = hi.iItem; pList->iHotSubItem = hi.iSubItem; if ((hi.flags & LVHT_ONITEMLABEL) && PtrIsValid(pItem = ProfileList_GetItemData(hwnd, hi.iItem))) { GetWindowRect(hwnd, &rchWnd); ListView_GetSubItemRect(hwnd, hi.iItem, hi.iSubItem, LVIR_BOUNDS, &rcItem); // calculate size of text on the screen if ((hDC = GetDC(GetParent(hwnd)))) { SelectObject(hDC, (HFONT)SendMessage(GetParent(hwnd), WM_GETFONT, NULL, NULL)); GetTextExtentPoint32(hDC, pItem->pszText[hi.iSubItem], lstrlen(pItem->pszText[hi.iSubItem]), &textSize); ReleaseDC(GetParent(hwnd), hDC); } // show tip only for text that is larger than te listview can display if (textSize.cx > rchWnd.right - rchWnd.left || textSize.cx > rcItem.right - rcItem.left) { ZeroMemory(&ti, sizeof(TOOLINFO)); ti.cbSize = sizeof(TOOLINFO); ti.uFlags = TTF_IDISHWND|TTF_SUBCLASS|TTF_TRANSPARENT; ti.hinst = ghInst; ti.hwnd = hwnd; ti.uId = (UINT_PTR)hwnd; ti.lpszText = pItem->pszText[hi.iSubItem]; ti.rect = rcItem; SendMessage(pList->hTip, TTM_SETMAXTIPWIDTH, 0, 300); SendMessage(pList->hTip, TTM_SETTOOLINFO, NULL, (LPARAM)&ti); if (pList->iHotSubItem > 0) { SendMessage(pList->hTip, TTM_SETTITLE, 1, (LPARAM) ((pItem->idstrList && pItem->iListItem > 0 && pItem->iListItem < pItem->idstrListCount) ? pItem->idstrList[pItem->iListItem].ptszTranslated : (pItem->pszText[0] && *pItem->pszText[0]) ? pItem->pszText[0] : TranslateT("<empty>")) ); InvalidateRect(pList->hTip, NULL, TRUE); } else SendMessage(pList->hTip, TTM_SETTITLE, 0, (LPARAM)""); SendMessage(pList->hTip, TTM_ACTIVATE, TRUE, (LPARAM)&ti); pList->ptTip.x = rchWnd.left + GET_X_LPARAM(lParam) - 16; pList->ptTip.y = rchWnd.top + rcItem.top; // no TTN_SHOW is called if bReposition is TRUE, so repose here! if (bReposition) { RECT rcTip; GetClientRect(pList->hTip, &rcTip); SetWindowPos(pList->hTip, hwnd, pList->ptTip.x, pList->ptTip.y - rcTip.bottom, 0, 0, SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE); } pList->wFlags |= LIF_TIPVISIBLE; return 0; } } if (pList->wFlags & LIF_TIPVISIBLE) { SendMessage(pList->hTip, TTM_ACTIVATE, FALSE, (LPARAM)&ti); pList->wFlags &= ~LIF_TIPVISIBLE; } } } return 0; // begin label edit case WM_LBUTTONDBLCLK: { LVHITTESTINFO hi; hi.pt.x = GET_X_LPARAM(lParam); hi.pt.y = GET_Y_LPARAM(lParam); if (ListView_SubItemHitTest(hwnd, &hi)) { ProfileList_BeginLabelEdit(hwnd, hi.iItem, hi.iSubItem); } return TRUE; } case WM_NOTIFY: if (!PtrIsValid(pList = (LPLISTCTRL)GetUserData(hwnd))) break; // ensure position of tooltip is on the topline of the item if (((LPNMHDR)lParam)->hwndFrom == pList->hTip) { RECT rcTip; GetClientRect(pList->hTip, &rcTip); switch (((LPNMHDR)lParam)->code) { case TTN_SHOW: SetWindowPos(pList->hTip, hwnd, pList->ptTip.x, pList->ptTip.y - rcTip.bottom, 0, 0, SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE); return TRUE; } } break; case WM_COMMAND: { switch (LOWORD(wParam)) { // show dropdown menu for category list case BTN_EDIT: { INT i; TCHAR szEdit[MAX_PATH]; if (!PtrIsValid(pList = (LPLISTCTRL)GetUserData(hwnd))) break; GetWindowText(pList->labelEdit.hEdit, szEdit, MAX_PATH); // need to create the dropdown list? if (pList->labelEdit.dropDown.hDrop == NULL) { const INT listHeight = 120; RECT rc, rcList; INT add; // dropdown rect GetClientRect(pList->hList, &rcList); rc.left = pList->labelEdit.rcCombo.left; rc.right = pList->labelEdit.rcCombo.right + pList->labelEdit.rcCombo.bottom - pList->labelEdit.rcCombo.top; if (rcList.bottom < pList->labelEdit.rcCombo.bottom + listHeight) { rc.bottom = pList->labelEdit.rcCombo.bottom - 7; // don't ask me why! rc.top = rc.bottom - listHeight; } else { rc.top = pList->labelEdit.rcCombo.bottom; rc.bottom = rc.top + listHeight; } pList->labelEdit.dropDown.hDrop = CreateWindowEx(0, _T("LISTBOX"), NULL, WS_CHILD|WS_BORDER|WS_VSCROLL|LBS_COMBOBOX|LBS_HASSTRINGS, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, hwnd, NULL, ghInst, NULL); if (!pList->labelEdit.dropDown.hDrop) return FALSE; SetUserData(pList->labelEdit.dropDown.hDrop, pList); OldDropdownProc = (WNDPROC)SetWindowLongPtr(pList->labelEdit.dropDown.hDrop, GWLP_WNDPROC, (LONG_PTR)ProfileList_DropdownProc); SetWindowLongPtr(pList->labelEdit.dropDown.hDrop, GWLP_ID, LIST_DROPDOWN); SendMessage(pList->labelEdit.dropDown.hDrop, WM_SETFONT, (WPARAM)SendMessage(GetParent(pList->hList), WM_GETFONT, 0, 0), 0); // add items for (i = 0; i < pList->labelEdit.pItem->idstrListCount; i++) { add = ListBox_AddString(pList->labelEdit.dropDown.hDrop, pList->labelEdit.pItem->idstrList[i].ptszTranslated); ListBox_SetItemData(pList->labelEdit.dropDown.hDrop, add, pList->labelEdit.pItem->idstrList + i); if (!_tcscmp(szEdit, pList->labelEdit.pItem->idstrList[i].ptszTranslated)) ListBox_SetCurSel(pList->labelEdit.dropDown.hDrop, add); } } else { LPIDSTRLIST lpidList; i = 0; while (PtrIsValid(lpidList = (LPIDSTRLIST)ListBox_GetItemData(pList->labelEdit.dropDown.hDrop, i))) { if (!_tcscmp(szEdit, lpidList->ptszTranslated)) { ListBox_SetCurSel(pList->labelEdit.dropDown.hDrop, i); break; } i++; } if (i == pList->labelEdit.pItem->idstrListCount) ListBox_SetCurSel(pList->labelEdit.dropDown.hDrop, -1); } if (IsWindowVisible(pList->labelEdit.dropDown.hDrop)) { SetFocus(pList->labelEdit.hEdit); } else { ShowWindow(pList->labelEdit.dropDown.hDrop, SW_SHOW); //SetFocus(pList->labelEdit.dropDown.hDrop); } break; } } break; } case WM_MOUSEWHEEL: case WM_VSCROLL: case WM_HSCROLL: { if (PtrIsValid(pList = (LPLISTCTRL)GetUserData(hwnd))) ProfileList_EndLabelEdit(pList, FALSE); break; } case WM_KILLFOCUS: { HWND hwndFocus = GetFocus(); if (PtrIsValid(pList = (LPLISTCTRL)GetUserData(hwnd)) && pList->labelEdit.hEdit != hwndFocus && pList->labelEdit.dropDown.hDrop != hwndFocus && pList->labelEdit.hBtn != hwndFocus) ProfileList_EndLabelEdit(pList, FALSE); break; } case WM_DESTROY: if (PtrIsValid(pList = (LPLISTCTRL)GetUserData(hwnd))) { HFONT hFont; ProfileList_EndLabelEdit(pList, FALSE); ProfileList_Clear(hwnd); if (PtrIsValid(hFont = (HFONT)SendMessage(hwnd, WM_GETFONT, 0, 0)) && hFont != pList->hFont) DeleteObject(hFont); DestroyWindow(pList->hTip); mir_free(pList); } break; } return CallWindowProc(OldListViewProc, hwnd, msg, wParam, lParam); }
/** * name: DlgProcPspAbout() * desc: dialog procedure * * return: 0 or 1 **/ INT_PTR CALLBACK PSPProcContactProfile(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { HWND hList = GetDlgItem(hDlg, LIST_PROFILE); LPLISTCTRL pList; switch (uMsg) { case WM_INITDIALOG: { LVCOLUMN lvc; RECT rc; LOGFONT lf; HFONT hFont; TOOLINFO ti; if (!hList || !(pList = (LPLISTCTRL)mir_alloc(sizeof(LISTCTRL)))) return FALSE; ZeroMemory(pList, sizeof(LISTCTRL)); TranslateDialogDefault(hDlg); Ctrl_InitTextColours(); // init info structure pList->hList = hList; pList->nType = CTRL_LIST_PROFILE; ZeroMemory(&pList->labelEdit, sizeof(pList->labelEdit)); SetUserData(hList, pList); // set new window procedure OldListViewProc = (WNDPROC)SetWindowLongPtr(hList, GWLP_WNDPROC, (LONG_PTR)&ProfileList_SubclassProc); // remove static edge in aero mode if (IsAeroMode()) SetWindowLongPtr(hList, GWL_EXSTYLE, GetWindowLongPtr(hList, GWL_EXSTYLE)&~WS_EX_STATICEDGE); // insert columns into the listboxes ListView_SetExtendedListViewStyle(hList, LVS_EX_FULLROWSELECT); PSGetBoldFont(hDlg, hFont); SendDlgItemMessage(hDlg, IDC_PAGETITLE, WM_SETFONT, (WPARAM)hFont, 0); // set listfont pList->hFont = (HFONT)SendMessage(hList, WM_GETFONT, 0, 0); pList->wFlags |= LVF_EDITLABEL; GetObject(pList->hFont, sizeof(lf), &lf); lf.lfHeight -= 6; hFont = CreateFontIndirect(&lf); SendMessage(hList, WM_SETFONT, (WPARAM)hFont, 0); GetClientRect(hList, &rc); rc.right -= GetSystemMetrics(SM_CXVSCROLL); // initiate the tooltips pList->hTip = CreateWindowEx(WS_EX_TOPMOST, TOOLTIPS_CLASS, NULL, WS_POPUP|TTS_BALLOON|TTS_NOPREFIX|TTS_ALWAYSTIP, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hList, NULL, ghInst, NULL); if (pList->hTip) { SetWindowPos(pList->hTip, HWND_TOPMOST, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); ZeroMemory(&ti, sizeof(TOOLINFO)); ti.cbSize = sizeof(TOOLINFO); ti.uFlags = TTF_IDISHWND|TTF_SUBCLASS|TTF_TRANSPARENT; ti.hinst = ghInst; ti.hwnd = hList; ti.uId = (UINT_PTR)hList; SendMessage(pList->hTip, TTM_ADDTOOL, NULL, (LPARAM)&ti); SendMessage(pList->hTip, TTM_ACTIVATE, FALSE, (LPARAM)&ti); } // insert columns into the listboxes lvc.mask = LVCF_WIDTH; lvc.cx = rc.right / 8 * 3; ListView_InsertColumn(hList, 0, &lvc); lvc.cx = rc.right / 8 * 5; ListView_InsertColumn(hList, 1, &lvc); return TRUE; } case WM_CTLCOLORSTATIC: case WM_CTLCOLORDLG: if (IsAeroMode()) return (INT_PTR)GetStockBrush(WHITE_BRUSH); break; case WM_NOTIFY: switch (((LPNMHDR)lParam)->idFrom) { case 0: { HANDLE hContact = (HANDLE)((LPPSHNOTIFY)lParam)->lParam; LPCSTR pszProto; if (!PtrIsValid(pList = (LPLISTCTRL)GetUserData(hList))) break; switch (((LPNMHDR)lParam)->code) { // some account data may have changed so reread database case PSN_INFOCHANGED: { BYTE msgResult = 0; LPIDSTRLIST idList; UINT nList; BYTE i; INT iItem = 0, iGrp = 0, numProtoItems, numUserItems; if (!(pList->wFlags & CTRLF_CHANGED) && PSGetBaseProto(hDlg, pszProto) && *pszProto != 0) { ProfileList_Clear(hList); // insert the past information for (i = 0; i < 3; i++) { pFmt[i].GetList((WPARAM)&nList, (LPARAM)&idList); if ((numProtoItems = ProfileList_AddItemlistFromDB(pList, iItem, idList, nList, hContact, pszProto, pFmt[i].szCatFmt, pFmt[i].szValFmt, CTRLF_HASPROTO)) < 0) return FALSE; // scan all basic protocols for the subcontacts if (DB::Module::IsMetaAndScan(pszProto)) { INT iDefault = CallService(MS_MC_GETDEFAULTCONTACTNUM, (WPARAM)hContact, NULL); HANDLE hSubContact, hDefContact; LPCSTR pszSubBaseProto; INT j, numSubs; if ((hDefContact = (HANDLE)CallService(MS_MC_GETSUBCONTACT, (WPARAM)hContact, iDefault)) && (pszSubBaseProto = DB::Contact::Proto(hDefContact))) { if ((numProtoItems += ProfileList_AddItemlistFromDB(pList, iItem, idList, nList, hDefContact, pszSubBaseProto, pFmt[i].szCatFmt, pFmt[i].szValFmt, CTRLF_HASMETA|CTRLF_HASPROTO)) < 0) return FALSE; // copy the missing settings from the other subcontacts numSubs = CallService(MS_MC_GETNUMCONTACTS, (WPARAM)hContact, NULL); for (j = 0; j < numSubs; j++) { if (j == iDefault) continue; if (!(hSubContact = (HANDLE)CallService(MS_MC_GETSUBCONTACT, (WPARAM)hContact, j))) continue; if (!(pszSubBaseProto = DB::Contact::Proto(hSubContact))) continue; if ((numProtoItems += ProfileList_AddItemlistFromDB(pList, iItem, idList, nList, hSubContact, pszSubBaseProto, pFmt[i].szCatFmt, pFmt[i].szValFmt, CTRLF_HASMETA|CTRLF_HASPROTO)) < 0) return FALSE; //if ((numUserItems += ProfileList_AddItemlistFromDB(pList, iItem, idList, nList, hSubContact, USERINFO, pFmt[i].szCatFmt, pFmt[i].szValFmt, CTRLF_HASMETA|CTRLF_HASPROTO)) < 0) // return FALSE; } } } if ((numUserItems = ProfileList_AddItemlistFromDB(pList, iItem, idList, nList, hContact, USERINFO, pFmt[i].szCatFmt, pFmt[i].szValFmt, CTRLF_HASCUSTOM)) < 0) return FALSE; if (numUserItems || numProtoItems) { msgResult = PSP_CHANGED; ProfileList_AddGroup(hList, pFmt[i].szGroup, iGrp); iGrp = ++iItem; } } } SetWindowLongPtr(hDlg, DWLP_MSGRESULT, msgResult); break; } // user swiches to another propertysheetpage case PSN_KILLACTIVE: ProfileList_EndLabelEdit(hList, TRUE); break; // user selected to apply settings to the database case PSN_APPLY: if (pList->wFlags & CTRLF_CHANGED) { BYTE iFmt = -1; INT iItem; LVITEM lvi; TCHAR szGroup[MAX_PATH]; CHAR pszSetting[MAXSETTING]; LPLCITEM pItem; LPSTR pszModule = USERINFO; if (!hContact) PSGetBaseProto(hDlg, pszModule); *szGroup = 0; lvi.mask = LVIF_TEXT|LVIF_PARAM; lvi.pszText = szGroup; lvi.cchTextMax = MAX_PATH; for (iItem = lvi.iItem = lvi.iSubItem = 0; ListView_GetItem(hList, &lvi); lvi.iItem++) { if (!PtrIsValid(pItem = (LPLCITEM)lvi.lParam)) { // delete reluctant items if (iFmt >= 0 && iFmt < SIZEOF(pFmt)) { DB::Setting::DeleteArray(hContact, pszModule, pFmt[iFmt].szCatFmt, iItem); DB::Setting::DeleteArray(hContact, pszModule, pFmt[iFmt].szValFmt, iItem); } // find information about the group for (iFmt = 0; iFmt < SIZEOF(pFmt); iFmt++) { if (!_tcscmp(szGroup, pFmt[iFmt].szGroup)) { break; } } // indicate, no group was found. should not happen!! if (iFmt == SIZEOF(pFmt)) { *szGroup = 0; iFmt = -1; } iItem = 0; } else if (iFmt >= 0 && iFmt < SIZEOF(pFmt)) { // save value if (!pItem->pszText[1] || !*pItem->pszText[1]) continue; if (!(pItem->wFlags & (CTRLF_HASPROTO|CTRLF_HASMETA))) { mir_snprintf(pszSetting, MAXSETTING, pFmt[iFmt].szValFmt, iItem); DB::Setting::WriteTString(hContact, pszModule, pszSetting, pItem->pszText[1]); // save category mir_snprintf(pszSetting, MAXSETTING, pFmt[iFmt].szCatFmt, iItem); if (pItem->idstrList && pItem->iListItem > 0 && pItem->iListItem < pItem->idstrListCount) DB::Setting::WriteAString(hContact, pszModule, pszSetting, (LPSTR)pItem->idstrList[pItem->iListItem].pszText); else if (pItem->pszText[0] && *pItem->pszText[0]) DB::Setting::WriteTString(hContact, pszModule, pszSetting, (LPTSTR)pItem->pszText[0]); else DB::Setting::Delete(hContact, pszModule, pszSetting); // redraw the item if required if (pItem->wFlags & CTRLF_CHANGED) { pItem->wFlags &= ~CTRLF_CHANGED; ListView_RedrawItems(hList, lvi.iItem, lvi.iItem); } iItem++; } } } // delete reluctant items if (iFmt >= 0 && iFmt < SIZEOF(pFmt)) { DB::Setting::DeleteArray(hContact, pszModule, pFmt[iFmt].szCatFmt, iItem); DB::Setting::DeleteArray(hContact, pszModule, pFmt[iFmt].szValFmt, iItem); } pList->wFlags &= ~CTRLF_CHANGED; } break; } break; } // // handle notification messages from the list control // case LIST_PROFILE: { LPLISTCTRL pList = (LPLISTCTRL)GetUserData(((LPNMHDR)lParam)->hwndFrom); switch (((LPNMHDR)lParam)->code) { case NM_RCLICK: { HMENU hMenu = CreatePopupMenu(); MENUITEMINFO mii; HANDLE hContact; LVHITTESTINFO hi; LPLCITEM pItem; POINT pt; if (!hMenu) return 1; PSGetContact(hDlg, hContact); GetCursorPos(&pt); hi.pt = pt; ScreenToClient(((LPNMHDR)lParam)->hwndFrom, &hi.pt); ListView_SubItemHitTest(((LPNMHDR)lParam)->hwndFrom, &hi); pItem = ProfileList_GetItemData(((LPNMHDR)lParam)->hwndFrom, hi.iItem); // insert menuitems ZeroMemory(&mii, sizeof(MENUITEMINFO)); mii.cbSize = sizeof(MENUITEMINFO); mii.fMask = MIIM_ID|MIIM_STRING; // insert "Add" Menuitem mii.wID = BTN_ADD_intEREST; mii.dwTypeData = TranslateT("Add Interest"); InsertMenuItem(hMenu, 0, TRUE, &mii); mii.wID = BTN_ADD_AFFLIATION; mii.dwTypeData = TranslateT("Add Affliation"); InsertMenuItem(hMenu, 1, TRUE, &mii); mii.wID = BTN_ADD_PAST; mii.dwTypeData = TranslateT("Add Past"); InsertMenuItem(hMenu, 2, TRUE, &mii); if (hi.iItem != -1 && PtrIsValid(pItem) && !(hContact && (pItem->wFlags & CTRLF_HASPROTO))) { // insert separator mii.fMask = MIIM_FTYPE; mii.fType = MFT_SEPARATOR; InsertMenuItem(hMenu, 3, TRUE, &mii); // insert "Delete" Menuitem mii.fMask = MIIM_ID|MIIM_STRING; mii.wID = BTN_EDIT_CAT; mii.dwTypeData = TranslateT("Edit Category"); InsertMenuItem(hMenu, 4, TRUE, &mii); mii.wID = BTN_EDIT_VAL; mii.dwTypeData = TranslateT("Edit Value"); InsertMenuItem(hMenu, 5, TRUE, &mii); mii.fMask = MIIM_FTYPE; mii.fType = MFT_SEPARATOR; InsertMenuItem(hMenu, 6, TRUE, &mii); // insert "Delete" Menuitem mii.fMask = MIIM_ID|MIIM_STRING; mii.wID = BTN_DEL; mii.dwTypeData = TranslateT("Delete"); InsertMenuItem(hMenu, 7, TRUE, &mii); } TrackPopupMenu(hMenu, 0, pt.x, pt.y, 0, hDlg, 0); DestroyMenu(hMenu); return 0; } /*case LVN_BEGINSCROLL: SetFocus(((LPNMHDR)lParam)->hwndFrom); break; */ case LVN_GETDISPINFO: if (pList->labelEdit.iTopIndex != ListView_GetTopIndex(hList)) ProfileList_EndLabelEdit(((LPNMHDR)lParam)->hwndFrom, FALSE); break; case NM_CUSTOMDRAW: { LPNMLVCUSTOMDRAW cd = (LPNMLVCUSTOMDRAW)lParam; LPLCITEM pItem = (LPLCITEM)cd->nmcd.lItemlParam; RECT rc; switch (cd->nmcd.dwDrawStage) { case CDDS_PREPAINT: SetWindowLongPtr(hDlg, DWLP_MSGRESULT, CDRF_NOTIFYITEMDRAW); return TRUE; case CDDS_ITEMPREPAINT: ListView_GetItemRect(cd->nmcd.hdr.hwndFrom, cd->nmcd.dwItemSpec, &rc, LVIR_BOUNDS); if (!PtrIsValid(pItem)) { HFONT hBold, hFont; TCHAR szText[MAX_PATH]; PSGetBoldFont(hDlg, hBold); hFont = (HFONT)SelectObject(cd->nmcd.hdc, hBold); SetTextColor(cd->nmcd.hdc, GetSysColor(COLOR_3DSHADOW)); ProfileList_GetItemText(cd->nmcd.hdr.hwndFrom, cd->nmcd.dwItemSpec, 0, szText, MAX_PATH); rc.left += 6; DrawText(cd->nmcd.hdc, TranslateTS(szText), -1, &rc, DT_NOCLIP|DT_NOPREFIX|DT_SINGLELINE|DT_VCENTER); rc.bottom -= 2; rc.top = rc.bottom - 1; rc.left -= 6; DrawEdge(cd->nmcd.hdc, &rc, BDR_SUNKENOUTER, BF_RECT); SelectObject(cd->nmcd.hdc, hFont); SetWindowLongPtr(hDlg, DWLP_MSGRESULT, CDRF_SKIPDEFAULT); return TRUE; } // draw selected item if ((cd->nmcd.uItemState & CDIS_SELECTED) || (pList->labelEdit.iItem == cd->nmcd.dwItemSpec)) { SetTextColor(cd->nmcd.hdc, GetSysColor(COLOR_HIGHLIGHTTEXT)); FillRect(cd->nmcd.hdc, &rc, GetSysColorBrush(COLOR_HIGHLIGHT)); } // draw background of unselected item else { SetTextColor(cd->nmcd.hdc, (pItem->wFlags & CTRLF_CHANGED) ? clrChanged : (pItem->wFlags & CTRLF_HASMETA) ? clrMeta : ((pItem->wFlags & (CTRLF_HASCUSTOM)) && (pItem->wFlags & CTRLF_HASPROTO)) ? clrBoth : (pItem->wFlags & CTRLF_HASCUSTOM) ? clrCustom : clrNormal); FillRect(cd->nmcd.hdc, &rc, GetSysColorBrush(COLOR_WINDOW)); } SetWindowLongPtr(hDlg, DWLP_MSGRESULT, CDRF_NEWFONT|CDRF_NOTIFYSUBITEMDRAW); return TRUE; case CDDS_SUBITEM|CDDS_ITEMPREPAINT: { HFONT hoFont = (HFONT)SelectObject(cd->nmcd.hdc, pList->hFont); ListView_GetSubItemRect(cd->nmcd.hdr.hwndFrom, cd->nmcd.dwItemSpec, cd->iSubItem, LVIR_BOUNDS, &rc); if (cd->iSubItem == 0) { RECT rc2; ListView_GetSubItemRect(cd->nmcd.hdr.hwndFrom, cd->nmcd.dwItemSpec, 1, LVIR_BOUNDS, &rc2); rc.right = rc2.left; } rc.left += 3; DrawText(cd->nmcd.hdc, pItem->pszText[cd->iSubItem] ? pItem->pszText[cd->iSubItem] : (cd->iSubItem == 0 && pItem->idstrList && pItem->iListItem > 0 && pItem->iListItem < pItem->idstrListCount) ? pItem->idstrList[pItem->iListItem].ptszTranslated : TranslateT("<empty>"), -1, &rc, DT_END_ELLIPSIS|DT_NOCLIP|DT_NOPREFIX|DT_SINGLELINE|DT_VCENTER); SetWindowLongPtr(hDlg, DWLP_MSGRESULT, CDRF_SKIPDEFAULT); return TRUE; } } /* switch (cd->nmcd.dwDrawStage) */ break; } /* case NM_CUSTOMDRAW: */ } /* (((LPNMHDR)lParam)->code) */ break; } } break; /* case WM_NOTIFY: */ case WM_COMMAND: { switch (LOWORD(wParam)) { case BTN_ADD_intEREST: return ProfileList_AddNewItem(hDlg, (LPLISTCTRL)GetUserData(hList), &pFmt[2]); case BTN_ADD_AFFLIATION: return ProfileList_AddNewItem(hDlg, (LPLISTCTRL)GetUserData(hList), &pFmt[1]); case BTN_ADD_PAST: return ProfileList_AddNewItem(hDlg, (LPLISTCTRL)GetUserData(hList), &pFmt[0]); case BTN_EDIT_CAT: ProfileList_BeginLabelEdit(hList, ListView_GetSelectionMark(hList), 0); break; case BTN_EDIT_VAL: ProfileList_BeginLabelEdit(hList, ListView_GetSelectionMark(hList), 1); break; case BTN_DEL: if (IDYES == MsgBox(hDlg, MB_YESNO|MB_ICON_QUESTION, LPGENT("Question"), LPGENT("Delete an entry"), LPGENT("Do you really want to delete this entry?"))) { INT iItem = ListView_GetSelectionMark(hList); LPLISTCTRL pList = (LPLISTCTRL)GetUserData(hList); ProfileList_DeleteItem(hList, iItem); if (PtrIsValid(pList)) pList->wFlags |= CTRLF_CHANGED; SendMessage(GetParent(hDlg), PSM_CHANGED, NULL, NULL); // check if to delete any devider if (!ProfileList_GetItemData(hList, iItem--) && !ProfileList_GetItemData(hList, iItem)) ListView_DeleteItem(hList, iItem); } break; } break; } } return FALSE; }
INT_PTR CALLBACK WatchDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { case WM_INITDIALOG: { // setup the list... LVCOLUMN sLC; sLC.fmt = LVCFMT_LEFT; ListView_SetExtendedListViewStyle(GetDlgItem(hwnd, IDC_VARS), 32|LVS_EX_SUBITEMIMAGES); //LVS_EX_FULLROWSELECT sLC.mask = LVCF_FMT | LVCF_TEXT | LVCF_SUBITEM | LVCF_WIDTH; sLC.pszText = Translate("Contact"); sLC.cx = 80; ListView_InsertColumn(GetDlgItem(hwnd, IDC_VARS),0,&sLC); sLC.pszText = Translate("Module"); sLC.cx = 80; ListView_InsertColumn(GetDlgItem(hwnd, IDC_VARS),1,&sLC); sLC.pszText = Translate("Setting"); sLC.cx = 80; ListView_InsertColumn(GetDlgItem(hwnd, IDC_VARS),2,&sLC); sLC.pszText = Translate("Type"); sLC.cx = 60; ListView_InsertColumn(GetDlgItem(hwnd, IDC_VARS),3,&sLC); sLC.pszText = Translate("Data"); sLC.cx = 300; ListView_InsertColumn(GetDlgItem(hwnd, IDC_VARS),4,&sLC); PopulateWatchedWindow(GetDlgItem(hwnd, IDC_VARS)); TranslateMenu(GetMenu(hwnd)); TranslateMenu(GetSubMenu(GetMenu(hwnd),0)); TranslateDialogDefault(hwnd); // do the icon SendMessage(hwnd,WM_SETICON,ICON_BIG,(LPARAM)LoadIcon(hInst,MAKEINTRESOURCE(ICO_REGEDIT))); } return TRUE; // for the resize case WM_GETMINMAXINFO: { MINMAXINFO *mmi=(MINMAXINFO*)lParam; mmi->ptMinTrackSize.x=200; mmi->ptMinTrackSize.y=90; return 0; } case WM_SIZE: { UTILRESIZEDIALOG urd; ZeroMemory(&urd,sizeof(urd)); urd.cbSize=sizeof(urd); urd.hInstance=hInst; urd.hwndDlg=hwnd; urd.lParam=0; urd.lpTemplate=MAKEINTRESOURCE(IDD_WATCH_DIAG); urd.pfnResizer=WatchDialogResize; CallService(MS_UTILS_RESIZEDIALOG,0,(LPARAM)&urd); break; } case WM_COMMAND: switch(LOWORD(wParam)) { case MENU_REMALL_WATCHES: freeAllWatches(); ListView_DeleteAllItems(GetDlgItem(hwnd, IDC_VARS)); break; case MENU_EXIT: case IDCANCEL: hwnd2watchedVarsWindow = 0; DestroyWindow(hwnd); break; case MENU_REFRESH: PopulateWatchedWindow(GetDlgItem(hwnd, IDC_VARS)); } break; case WM_NOTIFY: switch(LOWORD(wParam)) { case IDC_VARS: switch(((NMHDR*)lParam)->code) { case NM_DBLCLK: { LVHITTESTINFO hti; LVITEM lvi; hti.pt=((NMLISTVIEW*)lParam)->ptAction; if (ListView_SubItemHitTest(GetDlgItem(hwnd,IDC_VARS),&hti) >-1) { if (hti.flags&LVHT_ONITEM) { lvi.mask = LVIF_PARAM; lvi.iItem = hti.iItem; lvi.iSubItem = 0; if (ListView_GetItem(GetDlgItem(hwnd,IDC_VARS),&lvi)) { ItemInfo ii; ii.hContact = (MCONTACT)lvi.lParam; ListView_GetItemText(GetDlgItem(hwnd,IDC_VARS),hti.iItem,1,ii.module,128); ListView_GetItemText(GetDlgItem(hwnd,IDC_VARS),hti.iItem,2,ii.setting,128); ii.type = FW_SETTINGNAME; SendMessage(hwnd2mainWindow,WM_FINDITEM,(WPARAM)&ii,0); } } } } break; } break; } break; } return 0; }
INT_PTR CALLBACK FindWindowDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_INITDIALOG: SendDlgItemMessage(hwnd, IDC_SBAR, SB_SETTEXT, 0, (LPARAM)TranslateT("Enter a string to search the database for")); CheckDlgButton(hwnd, IDC_MODNAME, BST_CHECKED); CheckDlgButton(hwnd, IDC_SETTINGNAME, BST_CHECKED); CheckDlgButton(hwnd, IDC_SETTINGVALUE, BST_CHECKED); CheckDlgButton(hwnd, IDC_FOUND, BST_CHECKED); SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM)LoadIcon(hInst, MAKEINTRESOURCE(ICO_REGEDIT))); SetWindowLongPtr(GetDlgItem(hwnd, IDC_REPLACE), GWLP_USERDATA, 0); SetWindowLongPtr(GetDlgItem(hwnd, IDC_SEARCH), GWLP_USERDATA, 0); SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_APPWINDOW); // taskbar icon TranslateDialogDefault(hwnd); ListView_SetExtendedListViewStyle(GetDlgItem(hwnd, IDC_LIST), 32 | LVS_EX_LABELTIP); // LVS_EX_GRIDLINES loadListSettings(GetDlgItem(hwnd, IDC_LIST), csResultList); Utils_RestoreWindowPositionNoMove(hwnd, NULL, modname, "Search_"); return TRUE; case WM_COMMAND: switch (LOWORD(wParam)) { case IDOK: case IDC_SEARCH: if (GetWindowLongPtr(GetDlgItem(hwnd, IDC_SEARCH), GWLP_USERDATA)) // stop the search SetWindowLongPtr(GetDlgItem(hwnd, IDC_SEARCH), GWLP_USERDATA, 0); else { TCHAR text[FLD_SIZE]; TCHAR replace[FLD_SIZE] = {0}; if (!GetDlgItemText(hwnd, IDC_TEXT, text, _countof(text)) && !IsDlgButtonChecked(hwnd, IDC_EXACT)) break; // empty replace is done only for exact match or entire replace if (LOWORD(wParam) == IDOK && !GetDlgItemText(hwnd, IDC_REPLACE, replace, _countof(replace)) && (!IsDlgButtonChecked(hwnd, IDC_ENTIRELY) && !IsDlgButtonChecked(hwnd, IDC_EXACT))) break; if (BST_UNCHECKED == IsDlgButtonChecked(hwnd, IDC_MODNAME) && BST_UNCHECKED == IsDlgButtonChecked(hwnd, IDC_SETTINGNAME) && BST_UNCHECKED == IsDlgButtonChecked(hwnd, IDC_SETTINGVALUE)) break; FindInfo *fi = (FindInfo*)mir_calloc(sizeof(FindInfo)); if (!fi) break; fi->hwnd = GetDlgItem(hwnd, IDC_LIST); fi->options = (IsDlgButtonChecked(hwnd, IDC_CASESENSITIVE) ? F_CASE : 0) | (IsDlgButtonChecked(hwnd, IDC_EXACT) ? F_EXACT : 0) | (IsDlgButtonChecked(hwnd, IDC_MODNAME) ? F_MODNAME : 0) | (IsDlgButtonChecked(hwnd, IDC_SETTINGNAME) ? F_SETNAME : 0) | (IsDlgButtonChecked(hwnd, IDC_SETTINGVALUE) ? F_SETVAL : 0); if (LOWORD(wParam) == IDOK) { if (IsDlgButtonChecked(hwnd, IDC_ENTIRELY)) fi->options |= F_ENTIRE; fi->replace = mir_tstrdup(replace); SetDlgItemText(hwnd, IDOK, TranslateT("Stop")); EnableWindow(GetDlgItem(hwnd, IDC_SEARCH), 0); } else { SetDlgItemText(hwnd, IDC_SEARCH, TranslateT("Stop")); EnableWindow(GetDlgItem(hwnd, IDOK), 0); } fi->search = mir_tstrdup(text); ListView_DeleteAllItems(fi->hwnd); SetWindowLongPtr(GetDlgItem(hwnd, IDC_SEARCH), GWLP_USERDATA, 1); EnableWindow(GetDlgItem(hwnd, IDCANCEL), 0); mir_forkthread(FindSettings, fi); } break; case IDCANCEL: DestroyWindow(hwnd); break; } break; case WM_GETMINMAXINFO: { MINMAXINFO *mmi = (MINMAXINFO*)lParam; mmi->ptMinTrackSize.x = 610; mmi->ptMinTrackSize.y = 300; } return 0; case WM_SIZE: Utils_ResizeDialog(hwnd, hInst, MAKEINTRESOURCEA(IDD_FIND), FindDialogResize); break; case WM_NOTIFY: if (LOWORD(wParam) != IDC_LIST) break; switch (((NMHDR*)lParam)->code) { case NM_DBLCLK: { LVHITTESTINFO hti; LVITEM lvi; HWND hwndResults = GetDlgItem(hwnd, IDC_LIST); hti.pt = ((NMLISTVIEW*)lParam)->ptAction; if (ListView_SubItemHitTest(hwndResults, &hti) > -1) { if (hti.flags&LVHT_ONITEM) { lvi.mask = LVIF_PARAM; lvi.iItem = hti.iItem; lvi.iSubItem = 0; if (ListView_GetItem(hwndResults, &lvi)) { ItemInfo ii = {0}; ii.hContact = (MCONTACT)lvi.lParam; ListView_GetItemTextA(hwndResults, hti.iItem, 2, ii.module, _countof(ii.module)); ListView_GetItemTextA(hwndResults, hti.iItem, 3, ii.setting, _countof(ii.setting)); if (ii.setting[0]) ii.type = FW_SETTINGNAME; else if (ii.module[0]) ii.type = FW_MODULE; SendMessage(hwnd2mainWindow, WM_FINDITEM, (WPARAM)&ii, 0); } } } break; } case LVN_COLUMNCLICK: { LPNMLISTVIEW lv = (LPNMLISTVIEW)lParam; ColumnsSortParams params; params.hList = GetDlgItem(hwnd, IDC_LIST); params.column = lv->iSubItem; params.last = lastColumn; ListView_SortItemsEx(params.hList, ColumnsCompare, (LPARAM)¶ms); lastColumn = (params.column == lastColumn) ? -1 : params.column; break; } } // switch break; case WM_DESTROY: ListView_DeleteAllItems(GetDlgItem(hwnd, IDC_LIST)); saveListSettings(GetDlgItem(hwnd, IDC_LIST), csResultList); Utils_SaveWindowPosition(hwnd, NULL, modname, "Search_"); break; } return 0; }
static INT_PTR CALLBACK JabberMucJidListDlgProc( HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam ) { JABBER_MUC_JIDLIST_INFO* dat = (JABBER_MUC_JIDLIST_INFO*)GetWindowLongPtr( hwndDlg, GWLP_USERDATA ); switch( msg ) { case WM_INITDIALOG: { LVCOLUMN lvc; RECT rc; HWND hwndList; TranslateDialogDefault( hwndDlg ); hwndList = GetDlgItem( hwndDlg, IDC_LIST ); ListView_SetExtendedListViewStyle(hwndList, LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES); GetClientRect( hwndList, &rc ); //rc.right -= GetSystemMetrics( SM_CXVSCROLL ); lvc.mask = LVCF_WIDTH; lvc.cx = rc.right - 20; ListView_InsertColumn( hwndList, 0, &lvc ); lvc.cx = 20; ListView_InsertColumn( hwndList, 1, &lvc ); SendMessage( hwndDlg, WM_JABBER_REFRESH, 0, lParam ); dat = (JABBER_MUC_JIDLIST_INFO*)lParam; static struct { int idc; char *title; char *icon; bool push; } buttons[] = { {IDC_BTN_FILTERAPPLY, "Apply filter", "sd_filter_apply", false}, {IDC_BTN_FILTERRESET, "Reset filter", "sd_filter_reset", false}, }; for (int i = 0; i < SIZEOF(buttons); ++i) { SendDlgItemMessage(hwndDlg, buttons[i].idc, BM_SETIMAGE, IMAGE_ICON, (LPARAM)dat->ppro->LoadIconEx(buttons[i].icon)); SendDlgItemMessage(hwndDlg, buttons[i].idc, BUTTONSETASFLATBTN, 0, 0); SendDlgItemMessage(hwndDlg, buttons[i].idc, BUTTONADDTOOLTIP, (WPARAM)buttons[i].title, 0); if (buttons[i].push) SendDlgItemMessage(hwndDlg, buttons[i].idc, BUTTONSETASPUSHBTN, 0, 0); } Utils_RestoreWindowPosition(hwndDlg, NULL, dat->ppro->m_szModuleName, "jidListWnd_"); } return TRUE; case WM_SIZE: { UTILRESIZEDIALOG urd = {0}; urd.cbSize = sizeof(urd); urd.hInstance = hInst; urd.hwndDlg = hwndDlg; urd.lpTemplate = MAKEINTRESOURCEA(IDD_JIDLIST); urd.pfnResizer = sttJidListResizer; CallService(MS_UTILS_RESIZEDIALOG, 0, (LPARAM)&urd); RECT listrc; LVCOLUMN lvc; HWND hwndList = GetDlgItem( hwndDlg, IDC_LIST ); GetClientRect( hwndList, &listrc ); lvc.mask = LVCF_WIDTH; //listrc.right -= GetSystemMetrics( SM_CXVSCROLL ); lvc.cx = listrc.right - 20; SendMessage(hwndList, LVM_SETCOLUMN, 0, (LPARAM)&lvc); break; } break; case WM_JABBER_REFRESH: { // lParam is ( JABBER_MUC_JIDLIST_INFO * ) HXML iqNode, queryNode; const TCHAR* from; TCHAR title[256]; // Clear current GWL_USERDATA, if any if ( dat != NULL ) delete dat; // Set new GWL_USERDATA dat = ( JABBER_MUC_JIDLIST_INFO * ) lParam; SetWindowLongPtr( hwndDlg, GWLP_USERDATA, ( LONG_PTR ) dat ); // Populate displayed list from iqNode lstrcpyn( title, TranslateT( "JID List" ), SIZEOF( title )); if (( dat=( JABBER_MUC_JIDLIST_INFO * ) lParam ) != NULL ) { if (( iqNode = dat->iqNode ) != NULL ) { if (( from = xmlGetAttrValue( iqNode, _T("from"))) != NULL ) { dat->roomJid = mir_tstrdup( from ); if (( queryNode = xmlGetChild( iqNode , "query" )) != NULL ) { TCHAR* localFrom = mir_tstrdup( from ); mir_sntprintf( title, SIZEOF( title ), TranslateT("%s, %d items (%s)"), ( dat->type == MUC_VOICELIST ) ? TranslateT( "Voice List" ) : ( dat->type == MUC_MEMBERLIST ) ? TranslateT( "Member List" ) : ( dat->type == MUC_MODERATORLIST ) ? TranslateT( "Moderator List" ) : ( dat->type == MUC_BANLIST ) ? TranslateT( "Ban List" ) : ( dat->type == MUC_ADMINLIST ) ? TranslateT( "Admin List" ) : ( dat->type == MUC_OWNERLIST ) ? TranslateT( "Owner List" ) : TranslateT( "JID List" ), xmlGetChildCount(queryNode), localFrom ); mir_free( localFrom ); } } } } SetWindowText( hwndDlg, title ); SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_FILTER), GWLP_USERDATA, 0); sttFillJidList(hwndDlg); } break; case WM_NOTIFY: if (( ( LPNMHDR )lParam )->idFrom == IDC_LIST ) { switch (( ( LPNMHDR )lParam )->code ) { case NM_CUSTOMDRAW: { NMLVCUSTOMDRAW *nm = ( NMLVCUSTOMDRAW * ) lParam; switch ( nm->nmcd.dwDrawStage ) { case CDDS_PREPAINT: case CDDS_ITEMPREPAINT: SetWindowLongPtr( hwndDlg, DWLP_MSGRESULT, CDRF_NOTIFYSUBITEMDRAW ); return TRUE; case CDDS_SUBITEM|CDDS_ITEMPREPAINT: { RECT rc; HICON hIcon; ListView_GetSubItemRect( nm->nmcd.hdr.hwndFrom, nm->nmcd.dwItemSpec, nm->iSubItem, LVIR_LABEL, &rc ); if ( nm->iSubItem == 1 ) { if( nm->nmcd.lItemlParam == ( LPARAM )( -1 )) hIcon = ( HICON )LoadImage( hInst, MAKEINTRESOURCE( IDI_ADDCONTACT ), IMAGE_ICON, GetSystemMetrics( SM_CXSMICON ), GetSystemMetrics( SM_CYSMICON ), 0 ); else hIcon = ( HICON )LoadImage( hInst, MAKEINTRESOURCE( IDI_DELETE ), IMAGE_ICON, GetSystemMetrics( SM_CXSMICON ), GetSystemMetrics( SM_CYSMICON ), 0 ); DrawIconEx( nm->nmcd.hdc, ( rc.left+rc.right-GetSystemMetrics( SM_CXSMICON ))/2, ( rc.top+rc.bottom-GetSystemMetrics( SM_CYSMICON ))/2,hIcon, GetSystemMetrics( SM_CXSMICON ), GetSystemMetrics( SM_CYSMICON ), 0, GetSysColorBrush(COLOR_WINDOW), DI_NORMAL ); DestroyIcon( hIcon ); SetWindowLongPtr( hwndDlg, DWLP_MSGRESULT, CDRF_SKIPDEFAULT ); return TRUE; } } } } break; case NM_CLICK: { NMLISTVIEW *nm = ( NMLISTVIEW * ) lParam; LVITEM lvi; LVHITTESTINFO hti; TCHAR text[128]; if ( nm->iSubItem < 1 ) break; hti.pt.x = ( short ) LOWORD( GetMessagePos()); hti.pt.y = ( short ) HIWORD( GetMessagePos()); ScreenToClient( nm->hdr.hwndFrom, &hti.pt ); if ( ListView_SubItemHitTest( nm->hdr.hwndFrom, &hti ) == -1 ) break; if ( hti.iSubItem != 1 ) break; lvi.mask = LVIF_PARAM | LVIF_TEXT; lvi.iItem = hti.iItem; lvi.iSubItem = 0; lvi.pszText = text; lvi.cchTextMax = sizeof( text ); ListView_GetItem( nm->hdr.hwndFrom, &lvi ); if ( lvi.lParam == ( LPARAM )( -1 )) { TCHAR szBuffer[ 1024 ]; _tcscpy( szBuffer, dat->type2str()); if ( !dat->ppro->EnterString(szBuffer, SIZEOF(szBuffer), NULL, JES_COMBO, "gcAddNick_")) break; // Trim leading and trailing whitespaces TCHAR *p = szBuffer, *q; for ( p = szBuffer; *p!='\0' && isspace( BYTE( *p )); p++); for ( q = p; *q!='\0' && !isspace( BYTE( *q )); q++); if (*q != '\0') *q = '\0'; if (*p == '\0') break; TCHAR rsn[ 1024 ]; _tcscpy( rsn, dat->type2str()); if ( dat->type == MUC_BANLIST ) { dat->ppro->EnterString(rsn, SIZEOF(rsn), TranslateT("Reason to ban") , JES_COMBO, "gcAddReason_"); if ( szBuffer ) dat->ppro->AddMucListItem( dat, p , rsn); else dat->ppro->AddMucListItem( dat, p ); } else dat->ppro->AddMucListItem( dat, p ); } else { //delete TCHAR msgText[128]; mir_sntprintf( msgText, SIZEOF( msgText ), _T("%s %s?"), TranslateT( "Removing" ), text ); if ( MessageBox( hwndDlg, msgText, dat->type2str(), MB_YESNO|MB_SETFOREGROUND ) == IDYES ) { dat->ppro->DeleteMucListItem( dat, ( TCHAR* )lvi.lParam ); mir_free(( void * )lvi.lParam ); ListView_DeleteItem( nm->hdr.hwndFrom, hti.iItem ); } } } break; } break; } break; case WM_COMMAND: if ((LOWORD(wParam) == IDC_BTN_FILTERAPPLY) || ((LOWORD(wParam) == IDOK) && (GetFocus() == GetDlgItem(hwndDlg, IDC_FILTER)))) { SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_FILTER), GWLP_USERDATA, 1); sttFillJidList(hwndDlg); } else if ((LOWORD(wParam) == IDC_BTN_FILTERRESET) || ((LOWORD(wParam) == IDCANCEL) && (GetFocus() == GetDlgItem(hwndDlg, IDC_FILTER)))) { SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_FILTER), GWLP_USERDATA, 0); sttFillJidList(hwndDlg); } break; /* case WM_SETCURSOR: if ( LOWORD( LPARAM )!= HTCLIENT ) break; if ( GetForegroundWindow() == GetParent( hwndDlg )) { POINT pt; GetCursorPos( &pt ); ScreenToClient( hwndDlg,&pt ); SetFocus( ChildWindowFromPoint( hwndDlg,pt )); //ugly hack because listviews ignore their first click } break; */ case WM_CLOSE: { HWND hwndList; int count, i; LVITEM lvi; // Free lParam of the displayed list items hwndList = GetDlgItem( hwndDlg, IDC_LIST ); count = ListView_GetItemCount( hwndList ); lvi.mask = LVIF_PARAM; lvi.iSubItem = 0; for ( i=0; i<count; i++ ) { lvi.iItem = i; if ( ListView_GetItem( hwndList, &lvi ) == TRUE ) { if ( lvi.lParam!=( LPARAM )( -1 ) && lvi.lParam!=( LPARAM )( NULL )) { mir_free(( void * ) lvi.lParam ); } } } ListView_DeleteAllItems( hwndList ); CJabberProto* ppro = dat->ppro; switch ( dat->type ) { case MUC_VOICELIST: ppro->m_hwndMucVoiceList = NULL; break; case MUC_MEMBERLIST: ppro->m_hwndMucMemberList = NULL; break; case MUC_MODERATORLIST: ppro->m_hwndMucModeratorList = NULL; break; case MUC_BANLIST: ppro->m_hwndMucBanList = NULL; break; case MUC_ADMINLIST: ppro->m_hwndMucAdminList = NULL; break; case MUC_OWNERLIST: ppro->m_hwndMucOwnerList = NULL; break; } DestroyWindow( hwndDlg ); } break; case WM_DESTROY: // Clear GWL_USERDATA if ( dat != NULL ) { Utils_SaveWindowPosition(hwndDlg, NULL, dat->ppro->m_szModuleName, "jidListWnd_"); delete dat; } break; } return FALSE; }
static LRESULT CALLBACK PluginListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_CHAR: if (wParam == '\b') { if (szFilter.GetLength() > 0) szFilter.Truncate(szFilter.GetLength() - 1); } else { szFilter.AppendChar(wParam); for (int i = 0; i < arPluginList.getCount(); i++) { PluginListItemData *p = arPluginList[i]; if (!_tcsnicmp(szFilter, p->fileName, szFilter.GetLength())) { LVFINDINFO lvfi; lvfi.flags = LVFI_PARAM; lvfi.lParam = (LPARAM)p; int idx = ListView_FindItem(hwnd, 0, &lvfi); if (idx != -1) { ListView_SetItemState(hwnd, idx, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED); ListView_EnsureVisible(hwnd, idx, FALSE); if (timerID != 0) KillTimer(hwnd, timerID); timerID = SetTimer(hwnd, 1, 1500, 0); return TRUE; } } } szFilter.Truncate(szFilter.GetLength() - 1); MessageBeep((UINT)-1); } return TRUE; case WM_TIMER: if (wParam == 1) { KillTimer(hwnd, timerID); timerID = 0; szFilter.Empty(); } break; case WM_LBUTTONDOWN: LVHITTESTINFO hi; hi.pt.x = LOWORD(lParam); hi.pt.y = HIWORD(lParam); ListView_SubItemHitTest(hwnd, &hi); // Dynamically load/unload a plugin if ((hi.iSubItem == 0) && (hi.flags & LVHT_ONITEMICON)) { LVITEM lvi = { 0 }; lvi.mask = LVIF_IMAGE | LVIF_PARAM; lvi.stateMask = -1; lvi.iItem = hi.iItem; lvi.iSubItem = 0; if (ListView_GetItem(hwnd, &lvi)) { lvi.mask = LVIF_IMAGE; PluginListItemData *dat = (PluginListItemData*)lvi.lParam; if (lvi.iImage == 3) { // load plugin if (LoadPluginDynamically(dat)) { lvi.iImage = 2; ListView_SetItem(hwnd, &lvi); } } else if (lvi.iImage == 2) { // unload plugin if (UnloadPluginDynamically(dat)) { lvi.iImage = 3; ListView_SetItem(hwnd, &lvi); } } LoadStdPlugins(); } } } return mir_callNextSubclass(hwnd, PluginListWndProc, msg, wParam, lParam); }
bool ListView::HitTest(const Point oPoint, LVHITTESTINFO* pHitTest) { pHitTest->pt = (POINT)oPoint; return ListView_SubItemHitTest(Handle, pHitTest) != -1; }
LRESULT CALLBACK PropsProc(HWND hwnd, UINT iMessage, WPARAM wParam, LPARAM lParam) { NM_TREEVIEW *nm; RECT rs; LVHITTESTINFO_x hittest; switch (iMessage) { case WM_NOTIFY: nm = (NM_TREEVIEW*)lParam; switch (nm->hdr.code) { case LVN_GETDISPINFO: { LV_DISPINFO *plvdi = (LV_DISPINFO*)lParam; plvdi->item.mask |= LVIF_TEXT | LVIF_DI_SETITEM; plvdi->item.mask &= ~LVIF_IMAGE; switch (plvdi->item.iSubItem) { case 1: if (currentPropertyFuncs) { char buf[256]; LV_ITEM item; memset(&item, 0, sizeof(item)); item.iItem = plvdi->item.iItem; item.mask = LVIF_PARAM; ListView_GetItem(lvwindow, &item); currentPropertyFuncs->getText(buf, lvwindow, currentPropertyData, item.lParam); plvdi->item.pszText = buf; } else { plvdi->item.pszText = ""; } break; default: break; } } case NM_CUSTOMDRAW: return CustomDraw(hwnd, (LPNMLVCUSTOMDRAW)lParam); case NM_CLICK: GetCursorPos(&hittest.pt); ScreenToClient(lvwindow, &hittest.pt); if (currentPropertyWindow) { // PostMessage(hwnd, WM_KILLPROPSEDITOR, 0, 0); } else { ListView_SubItemHitTest(lvwindow, &hittest); if (hittest.flags & LVHT_ONITEM) { if (hittest.iSubItem == 1) { RECT r; LV_ITEM item; memset(&item, 0, sizeof(item)); item.iItem = hittest.iItem; item.mask = LVIF_PARAM; ListView_GetItem(lvwindow, &item); currentPropertyRow = item.lParam; currentPropertyWindow = currentPropertyFuncs->startEdit(lvwindow, currentPropertyRow, currentPropertyData); if (currentPropertyWindow) { SendMessage(currentPropertyWindow, WM_SETFONT, SendMessage(lvwindow, WM_GETFONT, 0, 0), 0); ListView_GetSubItemRect(lvwindow,hittest.iItem, 1, LVIR_BOUNDS, &r); SetWindowPos(currentPropertyWindow, NULL, r.left, r.top, r.right- r.left, r.bottom - r.top, SWP_NOZORDER | SWP_SHOWWINDOW); SetFocus(currentPropertyWindow); // well it might not be an edit window in which case this should be ignored SendMessage(currentPropertyWindow, EM_SETSEL, 0, -1); // well it might not be a combo box in which case this should be ignored SendMessage(currentPropertyWindow, CB_SHOWDROPDOWN, 1, 0); } } } } break; case NM_DBLCLK: GetCursorPos(&hittest.pt); ScreenToClient(lvwindow, &hittest.pt); return 0; case NM_RCLICK: GetCursorPos(&hittest.pt); ScreenToClient(lvwindow, &hittest.pt); break; } break; case WM_KILLPROPSEDITOR: if (currentPropertyFuncs) { currentPropertyFuncs->finishEdit(lvwindow, currentPropertyRow, currentPropertyWindow, currentPropertyData); currentPropertyWindow = NULL; } break; case WM_CREATE: GetClientRect(hwnd, &rs); lvwindow = CreateWindowEx(0, WC_LISTVIEW, "", WS_VISIBLE | WS_CHILD | LVS_REPORT | LVS_SINGLESEL, 0, 0, rs.right, rs.bottom, hwnd, (HMENU)ID_TREEVIEW, hInstance, NULL); font = CreateFontIndirect(&fontdata); SetListViewColumns(); break; case WM_SIZE: MoveWindow(lvwindow, 0, 0, LOWORD(lParam), HIWORD(lParam), 0); ResizeListViewColumns(); break; case WM_DESTROY: // ReleasePropInfo(); DestroyWindow(lvwindow); break; } return DefWindowProc(hwnd, iMessage, wParam, lParam); }
INT_PTR CALLBACK ServicesPageWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { UNREFERENCED_PARAMETER(lParam); UNREFERENCED_PARAMETER(wParam); switch (message) { case WM_INITDIALOG: { hServicesPage = hDlg; hServicesListCtrl = GetDlgItem(hServicesPage, IDC_SERVICES_LIST); // // Correctly display message strings. // LPCWSTR szOSVendor = (bIsWindows ? IDS_MICROSOFT : IDS_REACTOS); size_t itemLength = 0; LPWSTR szItem = NULL, szNewItem = NULL; itemLength = GetWindowTextLength(GetDlgItem(hServicesPage, IDC_STATIC_SERVICES_WARNING)) + 1; szItem = (LPWSTR)MemAlloc(0, itemLength * sizeof(WCHAR)); GetDlgItemText(hServicesPage, IDC_STATIC_SERVICES_WARNING, szItem, (int)itemLength); szNewItem = FormatString(szItem, szOSVendor); SetDlgItemText(hServicesPage, IDC_STATIC_SERVICES_WARNING, szNewItem); MemFree(szNewItem); MemFree(szItem); itemLength = GetWindowTextLength(GetDlgItem(hServicesPage, IDC_CBX_SERVICES_MASK_PROPRIETARY_SVCS)) + 1; szItem = (LPWSTR)MemAlloc(0, itemLength * sizeof(WCHAR)); GetDlgItemText(hServicesPage, IDC_CBX_SERVICES_MASK_PROPRIETARY_SVCS, szItem, (int)itemLength); szNewItem = FormatString(szItem, szOSVendor); SetDlgItemText(hServicesPage, IDC_CBX_SERVICES_MASK_PROPRIETARY_SVCS, szNewItem); MemFree(szNewItem); MemFree(szItem); // // Initialize the styles. // DWORD dwStyle = ListView_GetExtendedListViewStyle(hServicesListCtrl); ListView_SetExtendedListViewStyle(hServicesListCtrl, dwStyle | LVS_EX_FULLROWSELECT | LVS_EX_CHECKBOXES); SetWindowTheme(hServicesListCtrl, L"Explorer", NULL); // // Initialize the application page's controls. // LVCOLUMN column = {}; // First column : Service's name. column.mask = LVCF_TEXT | LVCF_WIDTH; column.pszText = LoadResourceString(hInst, IDS_SERVICES_COLUMN_SERVICE); column.cx = 150; ListView_InsertColumn(hServicesListCtrl, 0, &column); MemFree(column.pszText); // Second column : Whether the service is required or not. column.mask = LVCF_TEXT | LVCF_WIDTH; column.pszText = LoadResourceString(hInst, IDS_SERVICES_COLUMN_REQ); column.cx = 60; ListView_InsertColumn(hServicesListCtrl, 1, &column); MemFree(column.pszText); // Third column : Service's vendor. column.mask = LVCF_TEXT | LVCF_WIDTH; column.pszText = LoadResourceString(hInst, IDS_SERVICES_COLUMN_VENDOR); column.cx = 150; ListView_InsertColumn(hServicesListCtrl, 2, &column); MemFree(column.pszText); // Fourth column : Service's status. column.mask = LVCF_TEXT | LVCF_WIDTH; column.pszText = LoadResourceString(hInst, IDS_SERVICES_COLUMN_STATUS); column.cx = 60; ListView_InsertColumn(hServicesListCtrl, 3, &column); MemFree(column.pszText); // Fifth column : Service's disabled date. column.mask = LVCF_TEXT | LVCF_WIDTH; column.pszText = LoadResourceString(hInst, IDS_SERVICES_COLUMN_DATEDISABLED); column.cx = 120; ListView_InsertColumn(hServicesListCtrl, 4, &column); MemFree(column.pszText); // // Populate and sort the list. // GetServices(); ListView_Sort(hServicesListCtrl, 0); Update_Btn_States(hDlg); // Select the first item. ListView_SetItemState(hServicesListCtrl, 0, LVIS_SELECTED, LVIS_SELECTED); return TRUE; } case WM_DESTROY: { ClearServicesList(); userModificationsList.RemoveAll(); return 0; } case WM_COMMAND: { switch (LOWORD(wParam)) { case IDC_BTN_SERVICES_ACTIVATE: { BOOL bAreThereModifs = FALSE; int index = -1; // From the beginning. while ((index = ListView_GetNextItem(hServicesListCtrl, index, LVNI_ALL)) != -1) { bAreThereModifs = ValidateItem(index, TRUE, FALSE) || bAreThereModifs; // The order is verrrrrry important !!!! } if (bAreThereModifs) { Update_Btn_States(hDlg); PropSheet_Changed(GetParent(hServicesPage), hServicesPage); } return TRUE; } case IDC_BTN_SERVICES_DEACTIVATE: { BOOL bAreThereModifs = FALSE; int index = -1; // From the beginning. while ((index = ListView_GetNextItem(hServicesListCtrl, index, LVNI_ALL)) != -1) { bAreThereModifs = ValidateItem(index, FALSE, FALSE) || bAreThereModifs; // The order is verrrrrry important !!!! } if (bAreThereModifs) { Update_Btn_States(hDlg); PropSheet_Changed(GetParent(hServicesPage), hServicesPage); } return TRUE; } case IDC_CBX_SERVICES_MASK_PROPRIETARY_SVCS: { bMaskProprietarySvcs = !bMaskProprietarySvcs; GetServices(bMaskProprietarySvcs); Update_Btn_States(hDlg); return TRUE; } default: return FALSE; } return FALSE; } case UM_CHECKSTATECHANGE: { BOOL bNewCheckState = !!((ListView_GetCheckState(hServicesListCtrl, int(lParam)) + 1) % 2); if (ValidateItem(/*reinterpret_cast<int>*/ int(lParam), bNewCheckState, !HideEssentialServiceWarning())) { Update_Btn_States(hDlg); PropSheet_Changed(GetParent(hServicesPage), hServicesPage); } return TRUE; } case WM_NOTIFY: { if (reinterpret_cast<LPNMHDR>(lParam)->hwndFrom == hServicesListCtrl) { switch (reinterpret_cast<LPNMHDR>(lParam)->code) { case NM_CLICK: case NM_RCLICK: { DWORD dwpos = GetMessagePos(); LVHITTESTINFO ht = {}; ht.pt.x = GET_X_LPARAM(dwpos); ht.pt.y = GET_Y_LPARAM(dwpos); MapWindowPoints(HWND_DESKTOP /*NULL*/, hServicesListCtrl, &ht.pt, 1); /* * We use ListView_SubItemHitTest(...) and not ListView_HitTest(...) * because ListView_HitTest(...) returns bad flags when one clicks * on a sub-item different from 0. The flags then contain LVHT_ONITEMSTATEICON * which must not be obviously present in this case. */ ListView_SubItemHitTest(hServicesListCtrl, &ht); if (LVHT_ONITEMSTATEICON & ht.flags) { PostMessage(hDlg, UM_CHECKSTATECHANGE, 0, (LPARAM)ht.iItem); // Disable default behaviour. Needed for the UM_CHECKSTATECHANGE // custom notification to work as expected. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, TRUE); } return TRUE; } case NM_DBLCLK: case NM_RDBLCLK: { // We deactivate double-clicks. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, TRUE); return TRUE; } case LVN_KEYDOWN: { if (reinterpret_cast<LPNMLVKEYDOWN>(lParam)->wVKey == VK_SPACE) { int iItem = ListView_GetSelectionMark(hServicesListCtrl); PostMessage(hDlg, UM_CHECKSTATECHANGE, 0, (LPARAM)iItem); // Disable default behaviour. Needed for the UM_CHECKSTATECHANGE // custom notification to work as expected. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, TRUE); } return TRUE; } case LVN_COLUMNCLICK: { int iSortingColumn = reinterpret_cast<LPNMLISTVIEW>(lParam)->iSubItem; ListView_SortEx(hServicesListCtrl, iSortingColumn, iSortedColumn); iSortedColumn = iSortingColumn; return TRUE; } } } else { switch (reinterpret_cast<LPNMHDR>(lParam)->code) { case PSN_APPLY: { // Try to apply the modifications to the system. MessageBox(NULL, _T("In Services page: PSN_APPLY"), _T("Info"), MB_ICONINFORMATION); /* // // Move this away... // int iRetVal = MessageBox(NULL, _T("Would you really want to modify the configuration of your system ?"), _T("Warning"), MB_ICONWARNING | MB_YESNOCANCEL); if (iRetVal == IDYES /\* modifications are OK *\/) SetWindowLongPtr(hServicesPage, DWLP_MSGRESULT, PSNRET_NOERROR); else if (iRetVal == IDNO /\* modifications are not OK *\/) SetWindowLongPtr(hServicesPage, DWLP_MSGRESULT, PSNRET_NOERROR); else // if (iRetVal == IDCANCEL) // There was an error... SetWindowLongPtr(hServicesPage, DWLP_MSGRESULT, PSNRET_INVALID); */ // // We modify the services which are stored in the user modification list. // // 1- Open the Service Control Manager for modifications. SC_HANDLE hSCManager = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (hSCManager != NULL) { LPCWSTR svcName; for (POSITION it = userModificationsList.GetHeadPosition(); it; userModificationsList.GetNext(it)) { svcName = userModificationsList.GetAt(it); // 2- Retrieve a handle to the service. SC_HANDLE hService = OpenServiceW(hSCManager, svcName, SERVICE_QUERY_CONFIG | SERVICE_CHANGE_CONFIG); if (hService == NULL) { // TODO : Show a message box. continue; } DWORD dwBytesNeeded = 0; QueryServiceConfigW(hService, NULL, 0, &dwBytesNeeded); // if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) LPQUERY_SERVICE_CONFIG lpServiceConfig = (LPQUERY_SERVICE_CONFIG)MemAlloc(0, dwBytesNeeded); if (!lpServiceConfig) { CloseServiceHandle(hService); continue; // TODO ? Show a message box... } QueryServiceConfigW(hService, lpServiceConfig, dwBytesNeeded, &dwBytesNeeded); if (lpServiceConfig->dwStartType == SERVICE_DISABLED) // We have a disabled service which is becoming to be enabled. { // 3a- Retrive the properties of the disabled service from the registry. RegistryDisabledServiceItemParams params = {}; QUERY_REGISTRY_KEYS_TABLE KeysQueryTable[2] = {}; KeysQueryTable[0].QueryRoutine = GetRegistryKeyedDisabledServicesQueryRoutine; KeysQueryTable[0].EntryContext = ¶ms; RegQueryRegistryKeys(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Shared Tools\\MSConfig\\services", KeysQueryTable, (PVOID)svcName); if (bIsWindows && bIsPreVistaOSVersion && !params.bIsPresent) { QUERY_REGISTRY_VALUES_TABLE ValuesQueryTable[2] = {}; ValuesQueryTable[0].QueryRoutine = GetRegistryValuedDisabledServicesQueryRoutine; ValuesQueryTable[0].EntryContext = ¶ms; RegQueryRegistryValues(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Shared Tools\\MSConfig\\services", ValuesQueryTable, (PVOID)svcName); } if (params.bIsPresent) { // 4a- Modify the service. ChangeServiceConfigW(hService, SERVICE_NO_CHANGE, params.dwStartType, SERVICE_NO_CHANGE, NULL, NULL, NULL, NULL, NULL, NULL, NULL); // 5a- Remove the registry entry of the service. if (params.bIsKeyed) { CAtlStringW serviceRegKey(L"SOFTWARE\\Microsoft\\Shared Tools\\MSConfig\\services\\"); serviceRegKey += svcName; RegDeleteKeyW(HKEY_LOCAL_MACHINE, serviceRegKey); /***** HACK for Windows < Vista (e.g. 2000, Xp, 2003...) *****/ // // Delete also the valued-entry of the service. // if (bIsWindows && bIsPreVistaOSVersion) { HKEY hSubKey = NULL; if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Shared Tools\\MSConfig\\services", 0, KEY_SET_VALUE /*KEY_READ*/, &hSubKey) == ERROR_SUCCESS) { RegDeleteValue(hSubKey, svcName); RegCloseKey(hSubKey); } } /*************************************************************/ } else { HKEY hSubKey = NULL; if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Shared Tools\\MSConfig\\services", 0, KEY_SET_VALUE /*KEY_READ*/, &hSubKey) == ERROR_SUCCESS) { RegDeleteValue(hSubKey, svcName); RegCloseKey(hSubKey); } } ////////// HACKHACKHACKHACKHACKHACKHACKHACKHACKHACKHACK /////////// // userModificationsList.RemoveAt(it); } else { // Ohoh !! We have a very big problem. MessageBox(NULL, _T("WTF ??"), _T("FATAL ERROR !!!!"), MB_ICONERROR); } } else // We have an enabled service which is becoming to be disabled. { // 3b- Retrieve the local time of disabling. SYSTEMTIME disableDate = {}; GetLocalTime(&disableDate); // 4b- Modify the service. ChangeServiceConfigW(hService, SERVICE_NO_CHANGE, SERVICE_DISABLED, SERVICE_NO_CHANGE, NULL, NULL, NULL, NULL, NULL, NULL, NULL); // 5b- Register the service into the registry. CAtlStringW serviceRegKey(L"SOFTWARE\\Microsoft\\Shared Tools\\MSConfig\\services\\"); serviceRegKey += svcName; HKEY hSubKey = NULL; if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, serviceRegKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &hSubKey, NULL) == ERROR_SUCCESS) { RegSetDWORDValue(hSubKey, NULL, svcName, FALSE, lpServiceConfig->dwStartType); #if 1 // DisableDate RegSetDWORDValue(hSubKey, NULL, L"DAY" , FALSE, disableDate.wDay ); RegSetDWORDValue(hSubKey, NULL, L"HOUR" , FALSE, disableDate.wHour ); RegSetDWORDValue(hSubKey, NULL, L"MINUTE", FALSE, disableDate.wMinute); RegSetDWORDValue(hSubKey, NULL, L"MONTH" , FALSE, disableDate.wMonth ); RegSetDWORDValue(hSubKey, NULL, L"SECOND", FALSE, disableDate.wSecond); RegSetDWORDValue(hSubKey, NULL, L"YEAR" , FALSE, disableDate.wYear ); #endif RegCloseKey(hSubKey); } /***** HACK for Windows < Vista (e.g. 2000, Xp, 2003...) *****/ // // Save also a valued-entry for the service. // if (bIsWindows && bIsPreVistaOSVersion) { RegSetDWORDValue(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Shared Tools\\MSConfig\\services", svcName, TRUE, lpServiceConfig->dwStartType); } /*************************************************************/ ////////// HACKHACKHACKHACKHACKHACKHACKHACKHACKHACKHACK /////////// // userModificationsList.RemoveAt(it); } MemFree(lpServiceConfig); CloseServiceHandle(hService); } //////////// HACK HACK !!!! //////////// userModificationsList.RemoveAll(); //////////////////////////////////////// CloseServiceHandle(hSCManager); //// PropSheet_UnChanged(GetParent(hServicesPage), hServicesPage); //// PropSheet_CancelToClose(GetParent(hDlg)); /* Modifications are OK */ SetWindowLongPtr(hServicesPage, DWLP_MSGRESULT, PSNRET_NOERROR); } else { MessageBox(hDlg, _T("Impossible to open the SC manager..."), _T("Error"), MB_ICONERROR); // There was an error... SetWindowLongPtr(hServicesPage, DWLP_MSGRESULT, PSNRET_INVALID); } GetServices(bMaskProprietarySvcs); Update_Btn_States(hDlg); return TRUE; } case PSN_HELP: { MessageBox(hServicesPage, _T("Help not implemented yet!"), _T("Help"), MB_ICONINFORMATION | MB_OK); return TRUE; } case PSN_KILLACTIVE: // Is going to lose activation. { // Changes are always valid of course. SetWindowLongPtr(hServicesPage, DWLP_MSGRESULT, FALSE); return TRUE; } case PSN_QUERYCANCEL: { // RefreshStartupList(); // Allows cancellation. SetWindowLongPtr(hServicesPage, DWLP_MSGRESULT, FALSE); return TRUE; } case PSN_QUERYINITIALFOCUS: { // Give the focus on and select the first item. ListView_SetItemState(hServicesListCtrl, 0, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED); SetWindowLongPtr(hServicesPage, DWLP_MSGRESULT, (LONG_PTR)hServicesListCtrl); return TRUE; } // // DO NOT TOUCH THESE NEXT MESSAGES, THEY ARE OK LIKE THIS... // case PSN_RESET: // Perform final cleaning, called before WM_DESTROY. return TRUE; case PSN_SETACTIVE: // Is going to gain activation. { SetWindowLongPtr(hServicesPage, DWLP_MSGRESULT, 0); return TRUE; } default: break; } } } default: return FALSE; } return FALSE; }
static INT_PTR CALLBACK ContactDlgProc(HWND hwndDlg, UINT msg, WPARAM, LPARAM lParam) { const unsigned long iPageId = 5; CJabberProto *ppro = (CJabberProto*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); switch (msg) { case WM_INITDIALOG: if (!lParam) break; // Launched from userinfo ppro = (CJabberProto*)lParam; { LVCOLUMN lvc; RECT rc; SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam); TranslateDialogDefault(hwndDlg); GetClientRect(GetDlgItem(hwndDlg, IDC_EMAILS), &rc); rc.right -= GetSystemMetrics(SM_CXVSCROLL); lvc.mask = LVCF_WIDTH; lvc.cx = 30; ListView_InsertColumn(GetDlgItem(hwndDlg, IDC_EMAILS), 0, &lvc); ListView_InsertColumn(GetDlgItem(hwndDlg, IDC_PHONES), 0, &lvc); lvc.cx = rc.right - 30 - 40; ListView_InsertColumn(GetDlgItem(hwndDlg, IDC_EMAILS), 1, &lvc); ListView_InsertColumn(GetDlgItem(hwndDlg, IDC_PHONES), 1, &lvc); lvc.cx = 20; ListView_InsertColumn(GetDlgItem(hwndDlg, IDC_EMAILS), 2, &lvc); ListView_InsertColumn(GetDlgItem(hwndDlg, IDC_EMAILS), 3, &lvc); ListView_InsertColumn(GetDlgItem(hwndDlg, IDC_PHONES), 2, &lvc); ListView_InsertColumn(GetDlgItem(hwndDlg, IDC_PHONES), 3, &lvc); SendMessage(hwndDlg, M_REMAKELISTS, 0, 0); ppro->WindowSubscribe(hwndDlg); } break; case M_REMAKELISTS: { int i; char idstr[33]; TCHAR number[20]; //e-mails ListView_DeleteAllItems(GetDlgItem(hwndDlg, IDC_EMAILS)); LVITEM lvi; lvi.mask = LVIF_TEXT | LVIF_PARAM; lvi.iSubItem = 0; lvi.iItem = 0; for (i=0;;i++) { mir_snprintf(idstr, "e-mail%d", i); ptrT email( ppro->getTStringA(idstr)); if (email == NULL) break; mir_sntprintf(number, _T("%d"), i+1); lvi.pszText = number; lvi.lParam = (LPARAM)i; ListView_InsertItem(GetDlgItem(hwndDlg, IDC_EMAILS), &lvi); ListView_SetItemText(GetDlgItem(hwndDlg, IDC_EMAILS), lvi.iItem, 1, email); lvi.iItem++; } lvi.mask = LVIF_PARAM; lvi.lParam = -1; ListView_InsertItem(GetDlgItem(hwndDlg, IDC_EMAILS), &lvi); //phones ListView_DeleteAllItems(GetDlgItem(hwndDlg, IDC_PHONES)); lvi.mask = LVIF_TEXT | LVIF_PARAM; lvi.iSubItem = 0; lvi.iItem = 0; for (i=0;;i++) { mir_snprintf(idstr, "Phone%d", i); ptrT phone( ppro->getTStringA(idstr)); if (phone == NULL) break; mir_sntprintf(number, _T("%d"), i+1); lvi.pszText = number; lvi.lParam = (LPARAM)i; ListView_InsertItem(GetDlgItem(hwndDlg, IDC_PHONES), &lvi); ListView_SetItemText(GetDlgItem(hwndDlg, IDC_PHONES), lvi.iItem, 1, phone); lvi.iItem++; } lvi.mask = LVIF_PARAM; lvi.lParam = -1; ListView_InsertItem(GetDlgItem(hwndDlg, IDC_PHONES), &lvi); } break; case WM_NOTIFY: switch (((LPNMHDR)lParam)->idFrom) { case 0: switch (((LPNMHDR)lParam)->code) { case PSN_PARAMCHANGED: SendMessage(hwndDlg, WM_INITDIALOG, 0, ((PSHNOTIFY*)lParam)->lParam); break; case PSN_APPLY: ppro->m_vCardUpdates &= ~(1UL << iPageId); ppro->SaveVcardToDB(hwndDlg, iPageId); if (!ppro->m_vCardUpdates) ppro->SetServerVcard(ppro->m_bPhotoChanged, ppro->m_szPhotoFileName); break; } break; case IDC_EMAILS: case IDC_PHONES: switch (((LPNMHDR)lParam)->code) { case NM_CUSTOMDRAW: { NMLVCUSTOMDRAW *nm = (NMLVCUSTOMDRAW *)lParam; switch (nm->nmcd.dwDrawStage) { case CDDS_PREPAINT: case CDDS_ITEMPREPAINT: SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, CDRF_NOTIFYSUBITEMDRAW); return TRUE; case CDDS_SUBITEM | CDDS_ITEMPREPAINT: RECT rc; HICON hIcon; ListView_GetSubItemRect(nm->nmcd.hdr.hwndFrom, nm->nmcd.dwItemSpec, nm->iSubItem, LVIR_LABEL, &rc); if (nm->nmcd.lItemlParam == -1 && nm->iSubItem == 3) hIcon = (HICON)LoadImage(hInst, MAKEINTRESOURCE(IDI_ADDCONTACT), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 0); else if (nm->iSubItem == 2 && nm->nmcd.lItemlParam != -1) hIcon = (HICON)LoadImage(hInst, MAKEINTRESOURCE(IDI_EDIT), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 0); else if (nm->iSubItem == 3 && nm->nmcd.lItemlParam != -1) hIcon = (HICON)LoadImage(hInst, MAKEINTRESOURCE(IDI_DELETE), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 0); else break; DrawIconEx(nm->nmcd.hdc, (rc.left + rc.right - GetSystemMetrics(SM_CXSMICON)) / 2, (rc.top + rc.bottom - GetSystemMetrics(SM_CYSMICON)) / 2, hIcon, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 0, NULL, DI_NORMAL); DestroyIcon(hIcon); SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, CDRF_SKIPDEFAULT); return TRUE; } } break; case NM_CLICK: NMLISTVIEW *nm = (NMLISTVIEW *)lParam; if (nm->iSubItem < 2) break; const char* szIdTemplate = (nm->hdr.idFrom == IDC_PHONES) ? "Phone%d" : "e-mail%d"; const char* szFlagTemplate = (nm->hdr.idFrom == IDC_PHONES) ? "PhoneFlag%d" : "e-mailFlag%d"; LVHITTESTINFO hti; hti.pt.x = (short)LOWORD(GetMessagePos()); hti.pt.y = (short)HIWORD(GetMessagePos()); ScreenToClient(nm->hdr.hwndFrom, &hti.pt); if (ListView_SubItemHitTest(nm->hdr.hwndFrom, &hti) == -1) break; LVITEM lvi; lvi.mask = LVIF_PARAM; lvi.iItem = hti.iItem; lvi.iSubItem = 0; ListView_GetItem(nm->hdr.hwndFrom, &lvi); if (lvi.lParam == -1) { if (hti.iSubItem == 3) { //add EditDlgParam param = { -1, ppro }; int res; if (nm->hdr.idFrom == IDC_PHONES) res = DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_VCARD_ADDPHONE), hwndDlg, EditPhoneDlgProc, (LPARAM)¶m); else res = DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_VCARD_ADDEMAIL), hwndDlg, EditEmailDlgProc, (LPARAM)¶m); if (res != IDOK) break; SendMessage(hwndDlg, M_REMAKELISTS, 0, 0); ppro->m_vCardUpdates |= (1UL << iPageId); SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); } } else { if (hti.iSubItem == 3) { //delete char idstr[33]; int i; for (i = lvi.lParam;; i++) { mir_snprintf(idstr, szIdTemplate, i + 1); ptrA fieldVal(ppro->getStringA(idstr)); if (fieldVal == NULL) break; mir_snprintf(idstr, szIdTemplate, i); ppro->setString(idstr, fieldVal); mir_snprintf(idstr, szFlagTemplate, i + 1); WORD nFlag = ppro->getWord(idstr, 0); mir_snprintf(idstr, szFlagTemplate, i); ppro->setWord(idstr, nFlag); } mir_snprintf(idstr, szIdTemplate, i); ppro->delSetting(idstr); mir_snprintf(idstr, szFlagTemplate, i); ppro->delSetting(idstr); SendMessage(hwndDlg, M_REMAKELISTS, 0, 0); ppro->m_vCardUpdates |= (1UL << iPageId); SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); } else if (hti.iSubItem == 2) { EditDlgParam param = { (int)lvi.lParam, ppro }; int res; if (nm->hdr.idFrom == IDC_PHONES) res = DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_VCARD_ADDPHONE), hwndDlg, EditPhoneDlgProc, (LPARAM)¶m); else res = DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_VCARD_ADDEMAIL), hwndDlg, EditEmailDlgProc, (LPARAM)¶m); if (res != IDOK) break; SendMessage(hwndDlg, M_REMAKELISTS, 0, 0); ppro->m_vCardUpdates |= (1UL << iPageId); SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); } } } } break; case WM_SETCURSOR: if (LOWORD(lParam) != HTCLIENT) break; if (GetForegroundWindow() == GetParent(hwndDlg)) { POINT pt; GetCursorPos(&pt); ScreenToClient(hwndDlg, &pt); SetFocus(ChildWindowFromPoint(hwndDlg, pt)); //ugly hack because listviews ignore their first click } break; case WM_DESTROY: ppro->WindowUnsubscribe(hwndDlg); break; } return FALSE; }
INT_PTR CALLBACK ContactDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { case WM_INITDIALOG: SetWindowLongPtr(hwndDlg,GWLP_USERDATA,(LONG_PTR)lParam); if(hEmailFont) DeleteObject(hEmailFont); { LOGFONT lf; hEmailFont=(HFONT)SendDlgItemMessage(hwndDlg,IDC_EMAILS,WM_GETFONT,0,0); GetObject(hEmailFont,sizeof(lf),&lf); lf.lfUnderline=1; hEmailFont=CreateFontIndirect(&lf); } if(hHandCursor==NULL) { if(IsWinVer2000Plus()) hHandCursor=LoadCursor(NULL,IDC_HAND); else hHandCursor=LoadCursor(hMirandaInst,MAKEINTRESOURCE(IDC_HYPERLINKHAND)); } TranslateDialogDefault(hwndDlg); { LVCOLUMN lvc; RECT rc; GetClientRect(GetDlgItem(hwndDlg,IDC_EMAILS),&rc); rc.right-=GetSystemMetrics(SM_CXVSCROLL); lvc.mask=LVCF_WIDTH; ListView_SetExtendedListViewStyleEx(GetDlgItem(hwndDlg,IDC_EMAILS), LVS_EX_FULLROWSELECT | LVS_EX_INFOTIP, LVS_EX_FULLROWSELECT | LVS_EX_INFOTIP); ListView_SetExtendedListViewStyleEx(GetDlgItem(hwndDlg,IDC_PHONES), LVS_EX_FULLROWSELECT | LVS_EX_INFOTIP, LVS_EX_FULLROWSELECT | LVS_EX_INFOTIP); lvc.cx=rc.right/4; ListView_InsertColumn(GetDlgItem(hwndDlg,IDC_EMAILS),0,&lvc); ListView_InsertColumn(GetDlgItem(hwndDlg,IDC_PHONES),0,&lvc); lvc.cx=rc.right-rc.right/4-40; ListView_InsertColumn(GetDlgItem(hwndDlg,IDC_EMAILS),1,&lvc); lvc.cx=rc.right-rc.right/4-90; ListView_InsertColumn(GetDlgItem(hwndDlg,IDC_PHONES),1,&lvc); lvc.cx=50; ListView_InsertColumn(GetDlgItem(hwndDlg,IDC_PHONES),2,&lvc); lvc.cx=20; ListView_InsertColumn(GetDlgItem(hwndDlg,IDC_EMAILS),2,&lvc); ListView_InsertColumn(GetDlgItem(hwndDlg,IDC_EMAILS),3,&lvc); ListView_InsertColumn(GetDlgItem(hwndDlg,IDC_PHONES),3,&lvc); ListView_InsertColumn(GetDlgItem(hwndDlg,IDC_PHONES),4,&lvc); } break; case M_REMAKELISTS: { char *szProto; LVITEM lvi; int i; char idstr[33]; TCHAR idstr2[33]; DBVARIANT dbv; HANDLE hContact=(HANDLE)GetWindowLongPtr(hwndDlg,GWLP_USERDATA); if (hContact != NULL) { szProto=(char*)CallService(MS_PROTO_GETCONTACTBASEPROTO,(WPARAM)hContact,0); if (szProto==NULL) break; //e-mails ListView_DeleteAllItems(GetDlgItem(hwndDlg,IDC_EMAILS)); lvi.mask=LVIF_TEXT|LVIF_PARAM; lvi.lParam=(LPARAM)(-1); lvi.iSubItem=0; lvi.iItem=0; for(i=-1;;i++) { if(i==-1) { if(DBGetContactSettingTString(hContact,szProto,"e-mail",&dbv)) continue; lvi.pszText=TranslateT("Primary"); } else { mir_snprintf(idstr, SIZEOF(idstr), "e-mail%d", i ); if(DBGetContactSettingTString(hContact,szProto,idstr,&dbv)) break; lvi.pszText=idstr2; mir_sntprintf(idstr2, SIZEOF(idstr2), _T("%d"),i+2); } ListView_InsertItem(GetDlgItem(hwndDlg,IDC_EMAILS),&lvi); ListView_SetItemText(GetDlgItem(hwndDlg,IDC_EMAILS),lvi.iItem,1,dbv.ptszVal); DBFreeVariant(&dbv); lvi.iItem++; } lvi.iSubItem=0; for(i=0;;i++) { lvi.lParam=i; mir_snprintf(idstr, SIZEOF(idstr), "Mye-mail%d",i); if(DBGetContactSettingTString(hContact,"UserInfo",idstr,&dbv)) break; lvi.pszText=idstr2; mir_sntprintf(idstr2, SIZEOF(idstr2), TranslateT("Custom %d"),i+1); ListView_InsertItem(GetDlgItem(hwndDlg,IDC_EMAILS),&lvi); ListView_SetItemText(GetDlgItem(hwndDlg,IDC_EMAILS),lvi.iItem,1,dbv.ptszVal); DBFreeVariant(&dbv); lvi.iItem++; } lvi.mask=LVIF_PARAM; lvi.lParam=(LPARAM)(-2); ListView_InsertItem(GetDlgItem(hwndDlg,IDC_EMAILS),&lvi); //phones ListView_DeleteAllItems(GetDlgItem(hwndDlg,IDC_PHONES)); lvi.mask=LVIF_TEXT|LVIF_PARAM; lvi.lParam=(LPARAM)(-1); lvi.iSubItem=0; lvi.iItem=0; if(!DBGetContactSettingTString(hContact,szProto,"Phone",&dbv)) { lvi.pszText=TranslateT("Primary"); ListView_InsertItem(GetDlgItem(hwndDlg,IDC_PHONES),&lvi); ListView_SetItemText(GetDlgItem(hwndDlg,IDC_PHONES),lvi.iItem,1,dbv.ptszVal); DBFreeVariant(&dbv); lvi.iItem++; } if(!DBGetContactSettingTString(hContact,szProto,"Fax",&dbv)) { lvi.pszText=TranslateT("Fax"); ListView_InsertItem(GetDlgItem(hwndDlg,IDC_PHONES),&lvi); ListView_SetItemText(GetDlgItem(hwndDlg,IDC_PHONES),lvi.iItem,1,dbv.ptszVal); DBFreeVariant(&dbv); lvi.iItem++; } if(!DBGetContactSettingTString(hContact,szProto,"Cellular",&dbv)) { lvi.pszText=TranslateT("Mobile"); ListView_InsertItem(GetDlgItem(hwndDlg,IDC_PHONES),&lvi); if(lstrlenA(dbv.pszVal)>4 && !lstrcmpA(dbv.pszVal+lstrlenA(dbv.pszVal)-4," SMS")) { ListView_SetItemText(GetDlgItem(hwndDlg,IDC_PHONES),lvi.iItem,2,_T("y")); dbv.ptszVal[lstrlen(dbv.ptszVal)-4]='\0'; } ListView_SetItemText(GetDlgItem(hwndDlg,IDC_PHONES),lvi.iItem,1,dbv.ptszVal); DBFreeVariant(&dbv); lvi.iItem++; } if(!DBGetContactSettingTString(hContact,szProto,"CompanyPhone",&dbv)) { lvi.pszText=TranslateT("Work Phone"); ListView_InsertItem(GetDlgItem(hwndDlg,IDC_PHONES),&lvi); ListView_SetItemText(GetDlgItem(hwndDlg,IDC_PHONES),lvi.iItem,1,dbv.ptszVal); DBFreeVariant(&dbv); lvi.iItem++; } if(!DBGetContactSettingTString(hContact,szProto,"CompanyFax",&dbv)) { lvi.pszText=TranslateT("Work Fax"); ListView_InsertItem(GetDlgItem(hwndDlg,IDC_PHONES),&lvi); ListView_SetItemText(GetDlgItem(hwndDlg,IDC_PHONES),lvi.iItem,1,dbv.ptszVal); DBFreeVariant(&dbv); lvi.iItem++; } lvi.iSubItem=0; for(i=0;;i++) { lvi.lParam=i; mir_snprintf(idstr, SIZEOF(idstr), "MyPhone%d",i); if(DBGetContactSettingTString(hContact,"UserInfo",idstr,&dbv)) break; lvi.pszText=idstr2; mir_sntprintf(idstr2, SIZEOF(idstr2), TranslateT("Custom %d"),i+1); ListView_InsertItem(GetDlgItem(hwndDlg,IDC_PHONES),&lvi); if(lstrlen(dbv.ptszVal)>4 && !lstrcmp(dbv.ptszVal+lstrlen(dbv.ptszVal)-4,_T(" SMS"))) { ListView_SetItemText(GetDlgItem(hwndDlg,IDC_PHONES),lvi.iItem,2,_T("y")); dbv.ptszVal[lstrlen(dbv.ptszVal)-4]='\0'; } ListView_SetItemText(GetDlgItem(hwndDlg,IDC_PHONES),lvi.iItem,1,dbv.ptszVal); DBFreeVariant(&dbv); lvi.iItem++; } lvi.mask=LVIF_PARAM; lvi.lParam=(LPARAM)(-2); ListView_InsertItem(GetDlgItem(hwndDlg,IDC_PHONES),&lvi); } break; } case WM_NOTIFY: switch (((LPNMHDR)lParam)->idFrom) { case 0: switch (((LPNMHDR)lParam)->code) { case PSN_INFOCHANGED: SendMessage(hwndDlg,M_REMAKELISTS,0,0); break; } break; case IDC_EMAILS: case IDC_PHONES: switch (((LPNMHDR)lParam)->code) { case NM_CUSTOMDRAW: { NMLVCUSTOMDRAW *nm=(NMLVCUSTOMDRAW*)lParam; switch(nm->nmcd.dwDrawStage) { case CDDS_PREPAINT: case CDDS_ITEMPREPAINT: SetWindowLongPtr(hwndDlg,DWLP_MSGRESULT,CDRF_NOTIFYSUBITEMDRAW); return TRUE; case CDDS_SUBITEM|CDDS_ITEMPREPAINT: { RECT rc; ListView_GetSubItemRect(nm->nmcd.hdr.hwndFrom,nm->nmcd.dwItemSpec,nm->iSubItem,LVIR_LABEL,&rc); if(nm->iSubItem==1 && nm->nmcd.hdr.idFrom==IDC_EMAILS) { HFONT hoFont; TCHAR szText[256] = {0}; ListView_GetItemText(nm->nmcd.hdr.hwndFrom,nm->nmcd.dwItemSpec,nm->iSubItem,szText,SIZEOF(szText)); hoFont=(HFONT)SelectObject(nm->nmcd.hdc,hEmailFont); SetTextColor(nm->nmcd.hdc,RGB(0,0,255)); DrawText(nm->nmcd.hdc,szText,-1,&rc,DT_END_ELLIPSIS|DT_LEFT|DT_NOPREFIX|DT_SINGLELINE|DT_TOP); SelectObject(nm->nmcd.hdc,hoFont); SetWindowLongPtr(hwndDlg,DWLP_MSGRESULT,CDRF_SKIPDEFAULT); return TRUE; } HICON hIcon = NULL; if(nm->nmcd.lItemlParam==(LPARAM)(-2) && nm->iSubItem-3==(nm->nmcd.hdr.idFrom==IDC_PHONES)) hIcon = LoadSkinIcon( SKINICON_OTHER_ADDCONTACT ); else if(nm->iSubItem>1 && nm->nmcd.lItemlParam!=(LPARAM)(-1) && nm->nmcd.lItemlParam!=(LPARAM)(-2)) { static int iconResources[3]={SKINICON_OTHER_RENAME,SKINICON_OTHER_DELETE}; if(nm->iSubItem==2 && nm->nmcd.hdr.idFrom==IDC_PHONES) { TCHAR szText[2]; ListView_GetItemText(nm->nmcd.hdr.hwndFrom,nm->nmcd.dwItemSpec,nm->iSubItem,szText,SIZEOF(szText)); if(szText[0]) hIcon = LoadSkinIcon( SKINICON_OTHER_SMS ); } else hIcon = LoadSkinIcon( iconResources[nm->iSubItem-3+(nm->nmcd.hdr.idFrom==IDC_EMAILS)] ); } else break; DrawIconEx(nm->nmcd.hdc,(rc.left+rc.right-GetSystemMetrics(SM_CXSMICON))/2,(rc.top+rc.bottom-GetSystemMetrics(SM_CYSMICON))/2,hIcon,GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),0,NULL,DI_NORMAL); IconLib_ReleaseIcon(hIcon, 0); SetWindowLongPtr(hwndDlg,DWLP_MSGRESULT,CDRF_SKIPDEFAULT); return TRUE; } } break; } case NM_CLICK: { NMLISTVIEW *nm=(NMLISTVIEW*)lParam; LVITEM lvi; TCHAR szEmail[256]; HANDLE hContact=(HANDLE)GetWindowLongPtr(hwndDlg,GWLP_USERDATA); char *szIdTemplate=nm->hdr.idFrom==IDC_PHONES?"MyPhone%d":"Mye-mail%d"; LVHITTESTINFO hti; if(IsOverEmail(hwndDlg,szEmail,SIZEOF(szEmail))) { TCHAR szExec[264]; mir_sntprintf(szExec, SIZEOF(szExec), _T("mailto:%s"), szEmail); ShellExecute(hwndDlg,_T("open"),szExec,NULL,NULL,SW_SHOW); break; } if(nm->iSubItem<2) break; hti.pt.x=(short)LOWORD(GetMessagePos()); hti.pt.y=(short)HIWORD(GetMessagePos()); ScreenToClient(nm->hdr.hwndFrom,&hti.pt); if(ListView_SubItemHitTest(nm->hdr.hwndFrom,&hti)==-1) break; lvi.mask=LVIF_PARAM; lvi.iItem=hti.iItem; lvi.iSubItem=0; ListView_GetItem(nm->hdr.hwndFrom,&lvi); if(lvi.lParam==(LPARAM)(-1)) break; if(lvi.lParam==(LPARAM)(-2)) { if(hti.iSubItem-3==(nm->hdr.idFrom==IDC_PHONES)) { //add char szNewData[256]="",idstr[33]; int i; DBVARIANT dbv; if(IDOK!=DialogBoxParam(hMirandaInst,MAKEINTRESOURCE(nm->hdr.idFrom==IDC_PHONES?IDD_ADDPHONE:IDD_ADDEMAIL),hwndDlg,nm->hdr.idFrom==IDC_PHONES?EditUserPhoneDlgProc:EditUserEmailDlgProc,(LPARAM)szNewData)) break; for(i=0;;i++) { mir_snprintf(idstr, SIZEOF(idstr), szIdTemplate,i); if(DBGetContactSettingString(hContact,"UserInfo",idstr,&dbv)) break; DBFreeVariant(&dbv); } DBWriteContactSettingString(hContact,"UserInfo",idstr,szNewData); SendMessage(hwndDlg,M_REMAKELISTS,0,0); } } else { if(hti.iSubItem-3==(nm->hdr.idFrom==IDC_PHONES)) { //delete int i; char idstr[33]; DBVARIANT dbv; for(i=lvi.lParam;;i++) { mir_snprintf(idstr, SIZEOF(idstr), szIdTemplate,i+1); if(DBGetContactSettingString(hContact,"UserInfo",idstr,&dbv)) break; mir_snprintf(idstr, SIZEOF(idstr), szIdTemplate,i); DBWriteContactSettingString(hContact,"UserInfo",idstr,dbv.pszVal); DBFreeVariant(&dbv); } mir_snprintf(idstr, SIZEOF(idstr), szIdTemplate,i); DBDeleteContactSetting(hContact,"UserInfo",idstr); SendMessage(hwndDlg,M_REMAKELISTS,0,0); } else if(hti.iSubItem-2==(nm->hdr.idFrom==IDC_PHONES)) { //edit char szText[256],idstr[33]; DBVARIANT dbv; mir_snprintf(idstr, SIZEOF(idstr), szIdTemplate,lvi.lParam); if(DBGetContactSettingString(hContact,"UserInfo",idstr,&dbv)) break; lstrcpynA(szText,dbv.pszVal,SIZEOF(szText)); DBFreeVariant(&dbv); if(IDOK!=DialogBoxParam(hMirandaInst,MAKEINTRESOURCE(nm->hdr.idFrom==IDC_PHONES?IDD_ADDPHONE:IDD_ADDEMAIL),hwndDlg,nm->hdr.idFrom==IDC_PHONES?EditUserPhoneDlgProc:EditUserEmailDlgProc,(LPARAM)szText)) break; DBWriteContactSettingString(hContact,"UserInfo",idstr,szText); SendMessage(hwndDlg,M_REMAKELISTS,0,0); } } break; } } break; } break; case WM_SETCURSOR: if(LOWORD(lParam)!=HTCLIENT) break; if(GetForegroundWindow()==GetParent(hwndDlg)) { POINT pt; GetCursorPos(&pt); ScreenToClient(hwndDlg,&pt); // SetFocus(ChildWindowFromPoint(hwndDlg,pt)); //ugly hack because listviews ignore their first click } if(IsOverEmail(hwndDlg,NULL,0)) { SetCursor(hHandCursor); SetWindowLongPtr(hwndDlg,DWLP_MSGRESULT,TRUE); return TRUE; } break; case WM_COMMAND: switch(LOWORD(wParam)) { case IDCANCEL: SendMessage(GetParent(hwndDlg),msg,wParam,lParam); break; } break; } return FALSE; }