void Dlg_MemBookmark::PopulateList() { if ( m_vBookmarks.size() == 0 ) return; HWND hList = GetDlgItem( m_hMemBookmarkDialog, IDC_RA_LBX_ADDRESSES ); if ( hList == NULL ) return; int topIndex = ListView_GetTopIndex( hList ); ListView_DeleteAllItems( hList ); m_nNumOccupiedRows = 0; for ( MemBookmark* bookmark : m_vBookmarks ) { LV_ITEM item; ZeroMemory( &item, sizeof( item ) ); item.mask = LVIF_TEXT; item.cchTextMax = 256; item.iItem = m_nNumOccupiedRows; item.iSubItem = 0; item.iItem = ListView_InsertItem( hList, &item ); ASSERT( item.iItem == m_nNumOccupiedRows ); m_nNumOccupiedRows++; } ListView_EnsureVisible( hList, m_vBookmarks.size() - 1, FALSE ); // Scroll to bottom. //ListView_EnsureVisible( hList, topIndex, TRUE ); // return to last position. }
void SearchForText( short prev ) { char searchText[64]; GetWindowText( GetDlgItem( hDlg, IDC_LANGTOKEN_FINDTEXT), searchText, 64 ); if ( searchText[0] == 0 ) return; int nonRealTokenOffset = 0; char lineStr1[LANG_LINE_SIZE]; char lineStr2[LANG_LINE_SIZE]; int top = ListView_GetTopIndex( hWndLangBuilderListView ) + 1; int listviewsize = ListView_GetCountPerPage( hWndLangBuilderListView ); int bottom = top + listviewsize; int scrollOffset = 0; int item; /*if ( currItemSel+1 < top || currItemSel > bottom ) // Selected item is out of the list view (off the screen) { if ( currItemSel < top ) // Selected item is above the view scrollOffset = currItemSel - top - (listviewsize/2); // We can't see the selected item, so use the top of the view as the starting point for the search else // if ( currItemSel > bottom ) scrollOffset = currItemSel - top - (listviewsize/2); // } else*/ scrollOffset = currItemSel - top - (listviewsize/2); if ( prev ) { short i; item = currItemSel-1; // Since we can see the selected item in the list view, we start seaching right after it... for ( i = END_OF_STRINGS; i > SUMM_BEGIN; i-- ) { if ( CheckLangStringForTextPrev( searchText, lineStr1, lineStr2, i, scrollOffset, nonRealTokenOffset, item ) ) break; } if ( i == SUMM_BEGIN ) { sprintf( lineStr1, "The string '%s' is not in the language list", searchText ); MessageBox( GetFocus(), lineStr1, "String not found", MB_OK ); } } else { short i; item = currItemSel+1; // Since we can see the selected item in the list view, we start seaching right after it... for ( i = SUMM_BEGIN; i < END_OF_STRINGS; i++ ) { if ( CheckLangStringForText( searchText, lineStr1, lineStr2, i, scrollOffset, nonRealTokenOffset, item ) ) break; } if ( i == END_OF_STRINGS ) { sprintf( lineStr1, "The string '%s' is not in the language list", searchText ); MessageBox( GetFocus(), lineStr1, "String not found", MB_OK ); } } }
void wxCheckListBox::DoSetFirstItem(int n) { int pos = ListView_GetTopIndex( (HWND)GetHWND() ); if(pos == n) return; POINT ppt; BOOL ret = ListView_GetItemPosition( (HWND)GetHWND(), n, &ppt ); wxCHECK_RET( ret == TRUE, wxT("Broken DoSetFirstItem") ); ListView_Scroll( (HWND)GetHWND(), 0, 0 ); ListView_Scroll( (HWND)GetHWND(), 0, ppt.y ); }
extern "C" void Update_RAM_Watch() { if (!RamWatchHWnd) return; HWND lv; int top; int bottom; int start; int i; // update cached values and detect changes to displayed listview items int watchChanged[MAX_WATCH_COUNT] = {0}; for(i = 0; i < WatchCount; i++) { unsigned int prevCurValue = rswatches[i].CurValue; unsigned int newCurValue = GetCurrentValue(&rswatches[i]); if(prevCurValue != newCurValue) { rswatches[i].CurValue = newCurValue; watchChanged[i] = 1; } } // refresh any visible parts of the listview box that changed lv = GetDlgItem(RamWatchHWnd,IDC_WATCHLIST); top = ListView_GetTopIndex(lv); bottom = top + ListView_GetCountPerPage(lv) + 1; // +1 is so we will update a partially-displayed last item if(top < 0) top = 0; if(bottom > WatchCount) bottom = WatchCount; start = -1; for(i = top; i <= bottom; i++) { if(start == -1) { if(i != bottom && watchChanged[i]) { start = i; //somethingChanged = 1; } } else { if(i == bottom || !watchChanged[i]) { ListView_RedrawItems(lv, start, i-1); start = -1; } } } }
void Update_RAM_Watch() { BOOL watchChanged[MAX_WATCH_COUNT] = {0}; if(WatchCount) { // update cached values and detect changes to displayed listview items EnterCriticalSection(&g_processMemCS); for(int i = 0; i < WatchCount; i++) { RSVal prevCurValue = rswatches[i].CurValue; RSVal newCurValue = GetCurrentValue(rswatches[i]); if(!prevCurValue.CheckBinaryEquality(newCurValue)) { rswatches[i].CurValue = newCurValue; watchChanged[i] = TRUE; } } LeaveCriticalSection(&g_processMemCS); } // refresh any visible parts of the listview box that changed HWND lv = GetDlgItem(RamWatchHWnd,IDC_WATCHLIST); int top = ListView_GetTopIndex(lv); int bottom = top + ListView_GetCountPerPage(lv) + 1; // +1 is so we will update a partially-displayed last item if(top < 0) top = 0; if(bottom > WatchCount) bottom = WatchCount; int start = -1; for(int i = top; i <= bottom; i++) { if(start == -1) { if(i != bottom && watchChanged[i]) { start = i; //somethingChanged = true; } } else { if(i == bottom || !watchChanged[i]) { ListView_RedrawItems(lv, start, i-1); start = -1; } } } }
void PaintAlternatingRows (HWND hWnd) // re-draw rows with the appropriate background colour { int i; RECT rectUpd, // rectangle to update rectDestin, // temporary storage rect; // row rectangle POINT pt; int iItems, iTop; COLORREF c; // temporary storage // get the rectangle to be updated GetUpdateRect (hWnd, &rectUpd, FALSE); // allow default processing first CallWindowProc (old_lv_proc, hWnd, WM_PAINT, 0, 0); // set the row horizontal dimensions SetRect (&rect, rectUpd.left, 0, rectUpd.right, 0); // number of displayed rows iItems = ListView_GetCountPerPage (hWnd); // first visible row iTop = ListView_GetTopIndex (hWnd); ListView_GetItemPosition (hWnd, iTop, &pt); for (i=iTop ; i<=iTop+iItems ; i++) { // set row vertical dimensions rect.top = pt.y; ListView_GetItemPosition (hWnd, i+1, &pt); rect.bottom = pt.y; // if row rectangle intersects update rectangle then it requires // re-drawing if (IntersectRect (&rectDestin, &rectUpd, &rect)) { // change text background colour accordingly c = get_row_color(hWnd, i); ListView_SetTextBkColor (hWnd, c); // invalidate the row rectangle then... InvalidateRect (hWnd, &rect, FALSE); // ...force default processing CallWindowProc (old_lv_proc, hWnd, WM_PAINT, 0, 0); } } }
void EraseAlternatingRowBkgnds (HWND hWnd, HDC hDC) // re-draw row backgrounds with the appropriate background colour { int i; RECT rect; // row rectangle POINT pt; int iItems, iTop; HBRUSH brushes[MAX_LV_COLOR_NUM]; // create coloured brushes brushes[0]=CreateSolidBrush(lv_row_color[0]); brushes[1]=CreateSolidBrush(lv_row_color[1]); brushes[2]=CreateSolidBrush(lv_row_color[2]); brushes[3]=CreateSolidBrush(lv_row_color[3]); // get horizontal dimensions of row GetClientRect (hWnd, &rect); // number of displayed rows iItems = ListView_GetCountPerPage (hWnd); // first visible row iTop = ListView_GetTopIndex (hWnd); ListView_GetItemPosition (hWnd, iTop, &pt); for (i=iTop ; i<=iTop+iItems ; i++) { // set row vertical dimensions rect.top = pt.y; ListView_GetItemPosition (hWnd, i+1, &pt); rect.bottom = pt.y; // fill row with appropriate colour FillRect (hDC, &rect, brushes[get_row_color_idx(hWnd, i)]); } // cleanup DeleteObject (brushes[0]); DeleteObject (brushes[1]); DeleteObject (brushes[2]); DeleteObject (brushes[3]); }
/** * name: ProfileList_BeginLabelEdit * desc: create an edit control to edit the label of the selected item * param: pList - handle to listview control's info structure * iItem - item index * iSubItem - subitem (column) index * return: handle to the edit control **/ static HWND ProfileList_BeginLabelEdit(LPLISTCTRL pList, INT iItem, INT iSubItem) { LVITEM lvi; LPLCITEM pItem; HANDLE hContact; RECT rcList; if (!PtrIsValid(pList)) return NULL; if (pList->labelEdit.hEdit) ProfileList_EndLabelEdit(pList, FALSE); lvi.mask = LVIF_PARAM|LVIF_STATE; lvi.stateMask = 0xFFFFFFFF; lvi.iItem = iItem; lvi.iSubItem = iSubItem; if (!ListView_GetItem(pList->hList, &lvi)) return NULL; pItem = (LPLCITEM)lvi.lParam; PSGetContact(GetParent(pList->hList), hContact); // do not edit deviders or protocol based contact information if (!(lvi.state & LVIS_SELECTED) || !PtrIsValid(pItem) || (hContact && (pItem->wFlags & CTRLF_HASPROTO))) return NULL; ListView_EnsureVisible(pList->hList, iItem, FALSE); ListView_GetSubItemRect(pList->hList, iItem, iSubItem, LVIR_BOUNDS, &pList->labelEdit.rcCombo); if (lvi.iSubItem == 0) { RECT rc2; ListView_GetSubItemRect(pList->hList, iItem, 1, LVIR_BOUNDS, &rc2); pList->labelEdit.rcCombo.right = rc2.left; } GetClientRect(pList->hList, &rcList); pList->labelEdit.rcCombo.right = min(pList->labelEdit.rcCombo.right, rcList.right); pList->labelEdit.rcCombo.left = max(pList->labelEdit.rcCombo.left, rcList.left); InflateRect(&pList->labelEdit.rcCombo, -1, -1); // create the button control for the combobox if (!iSubItem && pItem->idstrList) { pList->labelEdit.hBtn = CreateWindowEx(WS_EX_NOPARENTNOTIFY, UINFOBUTTONCLASS, NULL, WS_VISIBLE|WS_CHILD|MBS_DOWNARROW, pList->labelEdit.rcCombo.right - (pList->labelEdit.rcCombo.bottom - pList->labelEdit.rcCombo.top), pList->labelEdit.rcCombo.top, pList->labelEdit.rcCombo.bottom - pList->labelEdit.rcCombo.top, pList->labelEdit.rcCombo.bottom - pList->labelEdit.rcCombo.top, pList->hList, NULL, ghInst, NULL); if (pList->labelEdit.hBtn) { SetWindowLongPtr(pList->labelEdit.hBtn, GWLP_ID, BTN_EDIT); pList->labelEdit.rcCombo.right -= pList->labelEdit.rcCombo.bottom - pList->labelEdit.rcCombo.top; } } else { pList->labelEdit.rcCombo.bottom = 3 * pList->labelEdit.rcCombo.bottom - 2 * pList->labelEdit.rcCombo.top; if (rcList.bottom < pList->labelEdit.rcCombo.bottom) { OffsetRect(&pList->labelEdit.rcCombo, 0, rcList.bottom - pList->labelEdit.rcCombo.bottom - 2); } } // create the edit control pList->labelEdit.hEdit = CreateWindowEx(WS_EX_NOPARENTNOTIFY|WS_EX_CLIENTEDGE, _T("EDIT"), (!iSubItem && pItem->idstrList && pItem->iListItem > 0 && pItem->iListItem < pItem->idstrListCount) ? pItem->idstrList[pItem->iListItem].ptszTranslated : (iSubItem >= 0 && iSubItem < 2 && pItem->pszText[iSubItem] && *pItem->pszText[iSubItem]) ? pItem->pszText[iSubItem] : _T(""), WS_VISIBLE|WS_CHILD|(iSubItem ? (WS_VSCROLL|ES_MULTILINE|ES_AUTOVSCROLL) : ES_AUTOHSCROLL), pList->labelEdit.rcCombo.left, pList->labelEdit.rcCombo.top, pList->labelEdit.rcCombo.right - pList->labelEdit.rcCombo.left, pList->labelEdit.rcCombo.bottom - pList->labelEdit.rcCombo.top, pList->hList, NULL, ghInst, NULL); if (!pList->labelEdit.hEdit) return NULL; SendMessage(pList->labelEdit.hEdit, WM_SETFONT, (WPARAM)(pList->hFont), 0); SendMessage(pList->labelEdit.hEdit, EM_SETSEL, 0, (LPARAM)-1); SetUserData(pList->labelEdit.hEdit, pList); pList->labelEdit.dropDown.iItem = pItem->iListItem; pList->labelEdit.iItem = iItem; pList->labelEdit.iSubItem = iSubItem; pList->labelEdit.iTopIndex = ListView_GetTopIndex(pList->hList); pList->labelEdit.pItem = pItem; SetFocus(pList->labelEdit.hEdit); OldEditProc = (WNDPROC)SetWindowLongPtr(pList->labelEdit.hEdit, GWLP_WNDPROC, (LONG_PTR)ProfileList_LabelEditProc); return pList->labelEdit.hEdit; }
/** * 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 ChangeInfoDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { ChangeInfoData* dat = (ChangeInfoData*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); switch (msg) { case WM_INITDIALOG: TranslateDialogDefault(hwndDlg); dat = new ChangeInfoData(); SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)dat); dat->hwndDlg = hwndDlg; dat->ppro = (CIcqProto*)lParam; dat->hwndList = GetDlgItem(hwndDlg, IDC_LIST); ListView_SetExtendedListViewStyle(dat->hwndList, LVS_EX_FULLROWSELECT); dat->iEditItem = -1; { dat->hListFont = (HFONT)SendMessage(dat->hwndList, WM_GETFONT, 0, 0); LOGFONT lf; GetObject(dat->hListFont, sizeof(lf), &lf); lf.lfHeight -= 5; HFONT hFont = CreateFontIndirect(&lf); SendMessage(dat->hwndList, WM_SETFONT, (WPARAM)hFont, 0); // Prepare ListView Columns RECT rc; GetClientRect(dat->hwndList, &rc); rc.right -= GetSystemMetrics(SM_CXVSCROLL); LV_COLUMN lvc = { 0 }; lvc.mask = LVCF_WIDTH; lvc.cx = rc.right / 3; ListView_InsertColumn(dat->hwndList, 0, &lvc); lvc.cx = rc.right - lvc.cx; ListView_InsertColumn(dat->hwndList, 1, &lvc); // Prepare Setting Items LV_ITEM lvi = { 0 }; lvi.mask = LVIF_PARAM | LVIF_TEXT; for (lvi.iItem = 0; lvi.iItem < settingCount; lvi.iItem++) { TCHAR text[MAX_PATH]; lvi.lParam = lvi.iItem; lvi.pszText = text; utf8_to_tchar_static(setting[lvi.iItem].szDescription, text, _countof(text)); ListView_InsertItem(dat->hwndList, &lvi); } } SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); return TRUE; case WM_NOTIFY: switch (((LPNMHDR)lParam)->idFrom) { case 0: switch (((LPNMHDR)lParam)->code) { case PSN_PARAMCHANGED: dat->ppro = (CIcqProto*)((PSHNOTIFY*)lParam)->lParam; dat->LoadSettingsFromDb(0); { char *pwd = dat->ppro->GetUserPassword(TRUE); mir_strcpy(dat->Password, (pwd) ? pwd : ""); /// FIXME } break; case PSN_INFOCHANGED: dat->LoadSettingsFromDb(1); break; case PSN_KILLACTIVE: dat->EndStringEdit(1); dat->EndListEdit(1); break; case PSN_APPLY: if (dat->ChangesMade()) { if (MessageBox(hwndDlg, TranslateT("You've made some changes to your ICQ details but it has not been saved to the server. Are you sure you want to close this dialog?"), TranslateT("Change ICQ Details"), MB_YESNOCANCEL) != IDYES) { SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE); return TRUE; } } } break; case IDC_LIST: switch (((LPNMHDR)lParam)->code) { case LVN_GETDISPINFO: if (dat->iEditItem != -1) { if (dat->editTopIndex != ListView_GetTopIndex(dat->hwndList)) { dat->EndStringEdit(1); dat->EndListEdit(1); } } break; case NM_CUSTOMDRAW: { LPNMLVCUSTOMDRAW cd = (LPNMLVCUSTOMDRAW)lParam; switch (cd->nmcd.dwDrawStage) { case CDDS_PREPAINT: SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, CDRF_NOTIFYITEMDRAW); return TRUE; case CDDS_ITEMPREPAINT: if (dat->iEditItem != -1) { if (dat->editTopIndex != ListView_GetTopIndex(dat->hwndList)) { dat->EndStringEdit(1); dat->EndListEdit(1); } } { RECT rcItem; ListView_GetItemRect(dat->hwndList, cd->nmcd.dwItemSpec, &rcItem, LVIR_BOUNDS); if (GetWindowLongPtr(dat->hwndList, GWL_STYLE) & WS_DISABLED) { // Disabled List SetTextColor(cd->nmcd.hdc, cd->clrText); FillRect(cd->nmcd.hdc, &rcItem, GetSysColorBrush(COLOR_3DFACE)); } else if ((cd->nmcd.uItemState & CDIS_SELECTED || dat->iEditItem == (int)cd->nmcd.dwItemSpec) && setting[cd->nmcd.lItemlParam].displayType != LI_DIVIDER) { // Selected item SetTextColor(cd->nmcd.hdc, GetSysColor(COLOR_HIGHLIGHTTEXT)); FillRect(cd->nmcd.hdc, &rcItem, GetSysColorBrush(COLOR_HIGHLIGHT)); } else { // Unselected item SetTextColor(cd->nmcd.hdc, GetSysColor(COLOR_WINDOWTEXT)); FillRect(cd->nmcd.hdc, &rcItem, GetSysColorBrush(COLOR_WINDOW)); } HFONT hoFont = (HFONT)SelectObject(cd->nmcd.hdc, dat->hListFont); if (setting[cd->nmcd.lItemlParam].displayType == LI_DIVIDER) { RECT rcLine; SIZE textSize; char str[MAX_PATH]; char *szText = ICQTranslateUtfStatic(setting[cd->nmcd.lItemlParam].szDescription, str, MAX_PATH); SetTextColor(cd->nmcd.hdc, GetSysColor(COLOR_3DSHADOW)); DrawTextUtf(cd->nmcd.hdc, szText, &rcItem, DT_CENTER | DT_NOCLIP | DT_NOPREFIX | DT_SINGLELINE | DT_VCENTER, &textSize); rcLine.top = (rcItem.top + rcItem.bottom) / 2 - 1; rcLine.bottom = rcLine.top + 2; rcLine.left = rcItem.left + 3; rcLine.right = (rcItem.left + rcItem.right - textSize.cx) / 2 - 3; DrawEdge(cd->nmcd.hdc, &rcLine, BDR_SUNKENOUTER, BF_RECT); rcLine.left = (rcItem.left + rcItem.right + textSize.cx) / 2 + 3; rcLine.right = rcItem.right - 3; DrawEdge(cd->nmcd.hdc, &rcLine, BDR_SUNKENOUTER, BF_RECT); } else { RECT rcItemDescr, rcItemValue; char str[MAX_PATH]; ListView_GetSubItemRect(dat->hwndList, cd->nmcd.dwItemSpec, 0, LVIR_BOUNDS, &rcItemDescr); ListView_GetSubItemRect(dat->hwndList, cd->nmcd.dwItemSpec, 1, LVIR_BOUNDS, &rcItemValue); rcItemDescr.right = rcItemValue.left; rcItemDescr.left += 2; DrawTextUtf(cd->nmcd.hdc, ICQTranslateUtfStatic(setting[cd->nmcd.lItemlParam].szDescription, str, MAX_PATH), &rcItemDescr, DT_END_ELLIPSIS | DT_LEFT | DT_NOCLIP | DT_NOPREFIX | DT_SINGLELINE | DT_VCENTER, NULL); dat->PaintItemSetting(cd->nmcd.hdc, &rcItemValue, cd->nmcd.lItemlParam, cd->nmcd.uItemState); } SelectObject(cd->nmcd.hdc, hoFont); SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, CDRF_SKIPDEFAULT); return TRUE; } } } break; case NM_CLICK: { LPNMLISTVIEW nm = (LPNMLISTVIEW)lParam; LV_ITEM lvi; RECT rc; dat->EndStringEdit(1); dat->EndListEdit(1); if (nm->iSubItem != 1) break; lvi.mask = LVIF_PARAM | LVIF_STATE; lvi.stateMask = 0xFFFFFFFF; lvi.iItem = nm->iItem; lvi.iSubItem = nm->iSubItem; ListView_GetItem(dat->hwndList, &lvi); if (!(lvi.state & LVIS_SELECTED)) break; ListView_EnsureVisible(dat->hwndList, lvi.iItem, FALSE); ListView_GetSubItemRect(dat->hwndList, lvi.iItem, lvi.iSubItem, LVIR_BOUNDS, &rc); dat->editTopIndex = ListView_GetTopIndex(dat->hwndList); switch (setting[lvi.lParam].displayType & LIM_TYPE) { case LI_STRING: case LI_LONGSTRING: case LI_NUMBER: dat->BeginStringEdit(nm->iItem, &rc, lvi.lParam, 0); break; case LI_LIST: dat->BeginListEdit(nm->iItem, &rc, lvi.lParam, 0); break; } } break; case LVN_KEYDOWN: { LPNMLVKEYDOWN nm = (LPNMLVKEYDOWN)lParam; LV_ITEM lvi; RECT rc; dat->EndStringEdit(1); dat->EndListEdit(1); if (nm->wVKey == VK_SPACE || nm->wVKey == VK_RETURN || nm->wVKey == VK_F2) nm->wVKey = 0; if (nm->wVKey && (nm->wVKey<'0' || (nm->wVKey>'9' && nm->wVKey<'A') || (nm->wVKey>'Z' && nm->wVKey < VK_NUMPAD0) || nm->wVKey >= VK_F1)) break; lvi.mask = LVIF_PARAM | LVIF_STATE; lvi.stateMask = 0xFFFFFFFF; lvi.iItem = ListView_GetNextItem(dat->hwndList, -1, LVNI_ALL | LVNI_SELECTED); if (lvi.iItem == -1) break; lvi.iSubItem = 1; ListView_GetItem(dat->hwndList, &lvi); ListView_EnsureVisible(dat->hwndList, lvi.iItem, FALSE); ListView_GetSubItemRect(dat->hwndList, lvi.iItem, lvi.iSubItem, LVIR_BOUNDS, &rc); dat->editTopIndex = ListView_GetTopIndex(dat->hwndList); switch (setting[lvi.lParam].displayType & LIM_TYPE) { case LI_STRING: case LI_LONGSTRING: case LI_NUMBER: dat->BeginStringEdit(lvi.iItem, &rc, lvi.lParam, nm->wVKey); break; case LI_LIST: dat->BeginListEdit(lvi.iItem, &rc, lvi.lParam, nm->wVKey); break; } SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, TRUE); } return TRUE; case NM_KILLFOCUS: if (!IsStringEditWindow(GetFocus())) dat->EndStringEdit(1); if (!IsListEditWindow(GetFocus())) dat->EndListEdit(1); } } break; case WM_KILLFOCUS: dat->EndStringEdit(1); dat->EndListEdit(1); break; case WM_COMMAND: switch (LOWORD(wParam)) { case IDCANCEL: SendMessage(GetParent(hwndDlg), msg, wParam, lParam); break; case IDC_SAVE: if (!dat->SaveSettingsToDb(hwndDlg)) break; EnableDlgItem(hwndDlg, IDC_SAVE, FALSE); EnableDlgItem(hwndDlg, IDC_LIST, FALSE); SetDlgItemText(hwndDlg, IDC_UPLOADING, TranslateT("Upload in progress...")); EnableDlgItem(hwndDlg, IDC_UPLOADING, TRUE); ShowDlgItem(hwndDlg, IDC_UPLOADING, SW_SHOW); dat->hAckHook = HookEventMessage(ME_PROTO_ACK, hwndDlg, DM_PROTOACK); if (!dat->UploadSettings()) { EnableDlgItem(hwndDlg, IDC_SAVE, TRUE); EnableDlgItem(hwndDlg, IDC_LIST, TRUE); ShowDlgItem(hwndDlg, IDC_UPLOADING, SW_HIDE); UnhookEvent(dat->hAckHook); dat->hAckHook = NULL; } } break; case WM_SIZE: if (IsIconic(hwndDlg)) break; Utils_ResizeDialog(hwndDlg, hInst, MAKEINTRESOURCEA(IDD_INFO_CHANGEINFO), ChangeInfoDlg_Resize); { RECT rc; // update listview column widths GetClientRect(dat->hwndList, &rc); rc.right -= GetSystemMetrics(SM_CXVSCROLL); ListView_SetColumnWidth(dat->hwndList, 0, rc.right / 3); ListView_SetColumnWidth(dat->hwndList, 1, rc.right - rc.right / 3); } break; case DM_PROTOACK: { ACKDATA *ack = (ACKDATA*)lParam; int i, done; if (ack->type != ACKTYPE_SETINFO) break; if (ack->result == ACKRESULT_SUCCESS) { for (i = 0; i < _countof(dat->hUpload); i++) if (dat->hUpload[i] && ack->hProcess == dat->hUpload[i]) break; if (i == _countof(dat->hUpload)) break; dat->hUpload[i] = NULL; for (done = 0, i = 0; i < _countof(dat->hUpload); i++) done += dat->hUpload[i] == NULL; TCHAR buf[MAX_PATH]; mir_sntprintf(buf, TranslateT("Upload in progress...%d%%"), 100 * done / (_countof(dat->hUpload))); SetDlgItemText(hwndDlg, IDC_UPLOADING, buf); if (done < _countof(dat->hUpload)) break; dat->ClearChangeFlags(); UnhookEvent(dat->hAckHook); dat->hAckHook = NULL; EnableDlgItem(hwndDlg, IDC_LIST, TRUE); EnableDlgItem(hwndDlg, IDC_UPLOADING, FALSE); SetDlgItemText(hwndDlg, IDC_UPLOADING, TranslateT("Upload complete")); SendMessage(GetParent(hwndDlg), PSM_FORCECHANGED, 0, 0); } else if (ack->result == ACKRESULT_FAILED) { UnhookEvent(dat->hAckHook); dat->hAckHook = NULL; EnableDlgItem(hwndDlg, IDC_LIST, TRUE); EnableDlgItem(hwndDlg, IDC_UPLOADING, FALSE); SetDlgItemText(hwndDlg, IDC_UPLOADING, TranslateT("Upload FAILED")); SendMessage(GetParent(hwndDlg), PSM_FORCECHANGED, 0, 0); EnableDlgItem(hwndDlg, IDC_SAVE, TRUE); } } break; case WM_DESTROY: if (dat->hAckHook) { UnhookEvent(dat->hAckHook); dat->hAckHook = NULL; } DeleteObject((HFONT)SendMessage(dat->hwndList, WM_GETFONT, 0, 0)); dat->FreeStoredDbSettings(); SetWindowLongPtr(hwndDlg, GWLP_USERDATA, 0); delete dat; break; } return FALSE; }
BOOL onListChar(HWND hWnd, HWND hwndList, WORD ch) { int i = 0; PNHMenuWindow data; int curIndex, topIndex, pageSize; boolean is_accelerator = FALSE; data = (PNHMenuWindow)GetWindowLong(hWnd, GWL_USERDATA); switch( ch ) { case MENU_FIRST_PAGE: i = 0; ListView_SetItemState(hwndList, i, LVIS_FOCUSED, LVIS_FOCUSED); ListView_EnsureVisible(hwndList, i, FALSE); return -2; case MENU_LAST_PAGE: i = max(0, data->menu.size-1); ListView_SetItemState(hwndList, i, LVIS_FOCUSED, LVIS_FOCUSED); ListView_EnsureVisible(hwndList, i, FALSE); return -2; case MENU_NEXT_PAGE: topIndex = ListView_GetTopIndex( hwndList ); pageSize = ListView_GetCountPerPage( hwndList ); curIndex = ListView_GetNextItem(hwndList, -1, LVNI_FOCUSED); /* Focus down one page */ i = min(curIndex+pageSize, data->menu.size-1); ListView_SetItemState(hwndList, i, LVIS_FOCUSED, LVIS_FOCUSED); /* Scrollpos down one page */ i = min(topIndex+(2*pageSize - 1), data->menu.size-1); ListView_EnsureVisible(hwndList, i, FALSE); return -2; case MENU_PREVIOUS_PAGE: topIndex = ListView_GetTopIndex( hwndList ); pageSize = ListView_GetCountPerPage( hwndList ); curIndex = ListView_GetNextItem(hwndList, -1, LVNI_FOCUSED); /* Focus up one page */ i = max(curIndex-pageSize, 0); ListView_SetItemState(hwndList, i, LVIS_FOCUSED, LVIS_FOCUSED); /* Scrollpos up one page */ i = max(topIndex-pageSize, 0); ListView_EnsureVisible(hwndList, i, FALSE); break; case MENU_SELECT_ALL: if( data->how == PICK_ANY ) { reset_menu_count(hwndList, data); for(i=0; i<data->menu.size; i++ ) { SelectMenuItem(hwndList, data, i, -1); } return -2; } break; case MENU_UNSELECT_ALL: if( data->how == PICK_ANY ) { reset_menu_count(hwndList, data); for(i=0; i<data->menu.size; i++ ) { SelectMenuItem(hwndList, data, i, 0); } return -2; } break; case MENU_INVERT_ALL: if( data->how == PICK_ANY ) { reset_menu_count(hwndList, data); for(i=0; i<data->menu.size; i++ ) { SelectMenuItem( hwndList, data, i, NHMENU_IS_SELECTED(data->menu.items[i])? 0 : -1 ); } return -2; } break; case MENU_SELECT_PAGE: if( data->how == PICK_ANY ) { int from, to; reset_menu_count(hwndList, data); topIndex = ListView_GetTopIndex( hwndList ); pageSize = ListView_GetCountPerPage( hwndList ); from = max(0, topIndex); to = min(data->menu.size, from+pageSize); for(i=from; i<to; i++ ) { SelectMenuItem(hwndList, data, i, -1); } return -2; } break; case MENU_UNSELECT_PAGE: if( data->how == PICK_ANY ) { int from, to; reset_menu_count(hwndList, data); topIndex = ListView_GetTopIndex( hwndList ); pageSize = ListView_GetCountPerPage( hwndList ); from = max(0, topIndex); to = min(data->menu.size, from+pageSize); for(i=from; i<to; i++ ) { SelectMenuItem(hwndList, data, i, 0); } return -2; } break; case MENU_INVERT_PAGE: if( data->how == PICK_ANY ) { int from, to; reset_menu_count(hwndList, data); topIndex = ListView_GetTopIndex( hwndList ); pageSize = ListView_GetCountPerPage( hwndList ); from = max(0, topIndex); to = min(data->menu.size, from+pageSize); for(i=from; i<to; i++ ) { SelectMenuItem( hwndList, data, i, NHMENU_IS_SELECTED(data->menu.items[i])? 0 : -1 ); } return -2; } break; case MENU_SEARCH: if( data->how==PICK_ANY || data->how==PICK_ONE ) { char buf[BUFSZ]; int selected_item; reset_menu_count(hwndList, data); mswin_getlin("Search for:", buf); if (!*buf || *buf == '\033') return -2; selected_item = -1; for(i=0; i<data->menu.size; i++ ) { if( NHMENU_IS_SELECTABLE(data->menu.items[i]) && strstr(data->menu.items[i].str, buf) ) { if (data->how == PICK_ANY) { SelectMenuItem( hwndList, data, i, NHMENU_IS_SELECTED(data->menu.items[i])? 0 : -1 ); /* save the first item - we will move focus to it */ if( selected_item == -1 ) selected_item = i; } else if( data->how == PICK_ONE ) { SelectMenuItem( hwndList, data, i, -1 ); selected_item = i; break; } } } if( selected_item>0 ) { ListView_SetItemState(hwndList, selected_item, LVIS_FOCUSED, LVIS_FOCUSED); ListView_EnsureVisible(hwndList, selected_item, FALSE); } } else { mswin_nhbell(); } return -2; case ' ': /* ends menu for PICK_ONE/PICK_NONE select item for PICK_ANY */ if( data->how==PICK_ONE || data->how==PICK_NONE ) { data->done = 1; data->result = 0; return -2; } else if( data->how==PICK_ANY ) { i = ListView_GetNextItem(hwndList, -1, LVNI_FOCUSED); if( i>=0 ) { SelectMenuItem( hwndList, data, i, NHMENU_IS_SELECTED(data->menu.items[i])? 0 : -1 ); } return -2; } break; default: if( strchr(data->menu.gacc, ch) && !(ch=='0' && data->menu.counting) ) { /* matched a group accelerator */ if (data->how == PICK_ANY || data->how == PICK_ONE) { reset_menu_count(hwndList, data); for(i=0; i<data->menu.size; i++ ) { if( NHMENU_IS_SELECTABLE(data->menu.items[i]) && data->menu.items[i].group_accel == ch ) { if( data->how == PICK_ANY ) { SelectMenuItem( hwndList, data, i, NHMENU_IS_SELECTED(data->menu.items[i])? 0 : -1 ); } else if( data->how == PICK_ONE ) { SelectMenuItem( hwndList, data, i, -1 ); data->result = 0; data->done = 1; return -2; } } } return -2; } else { mswin_nhbell(); return -2; } } if (isdigit(ch)) { int count; i = ListView_GetNextItem(hwndList, -1, LVNI_FOCUSED); if( i>=0 ) { count = data->menu.items[i].count; if( count==-1 ) count=0; count *= 10L; count += (int)(ch - '0'); if (count != 0) /* ignore leading zeros */ { data->menu.counting = TRUE; data->menu.items[i].count = min(100000, count); ListView_RedrawItems( hwndList, i, i ); /* update count mark */ } } return -2; } is_accelerator = FALSE; for(i=0; i<data->menu.size; i++) { if( data->menu.items[i].accelerator == ch ) { is_accelerator = TRUE; break; } } if( (ch>='a' && ch<='z') || (ch>='A' && ch<='Z') || is_accelerator) { if (data->how == PICK_ANY || data->how == PICK_ONE) { for(i=0; i<data->menu.size; i++ ) { if( data->menu.items[i].accelerator == ch ) { if( data->how == PICK_ANY ) { SelectMenuItem( hwndList, data, i, NHMENU_IS_SELECTED(data->menu.items[i])? 0 : -1 ); ListView_SetItemState(hwndList, i, LVIS_FOCUSED, LVIS_FOCUSED); ListView_EnsureVisible(hwndList, i, FALSE); return -2; } else if( data->how == PICK_ONE ) { SelectMenuItem( hwndList, data, i, -1 ); data->result = 0; data->done = 1; return -2; } } } } } break; } reset_menu_count(hwndList, data); return -1; }