/////////////////////////////////////////////////////////// // // // AdSearch.cpp - Implementation of the Advanced Search UI // // This source file implements the Advanced Search Navigation // pane class. /////////////////////////////////////////////////////////// // // Include section // #include "header.h" #include "strtable.h" // These headers were copied from search.cpp. Are they all needed? #include "system.h" #include "hhctrl.h" #include "resource.h" #include "secwin.h" #include "htmlhelp.h" #include "cpaldc.h" #include "TCHAR.h" #include "parserhh.h" #include "collect.h" #include "hhtypes.h" #include "toc.h" #include "contain.h" #include "cctlww.h" // Our header file. #include "bookmark.h" // Common Control Macros #include #define WS_EX_LAYOUTRTL 0x00400000L // Right to left mirroring /////////////////////////////////////////////////////////// // // Constants // const char c_PersistFolder[] = "Bookmarks\\v1" ; const char c_TopicFolder[] = "Topic" ; const char c_UrlFolder[] = "Url" ; const char c_CountFolder[] = "Bookmarks\\v1\\Count" ; const wchar_t c_KeywordSeparator[] = L"\n" ; // This is the maximum bookmarks we store. // The main reason for this is to ensure that we have a reasonable value // when we read the collection in. const int c_MaxBookmarks = 1024; extern BOOL g_fUnicodeListView; /////////////////////////////////////////////////////////// // // Static Member functions // WNDPROC CBookmarksNavPane::s_lpfnlListViewWndProc = NULL; WNDPROC CBookmarksNavPane::s_lpfnlCurrentTopicEditProc = NULL; WNDPROC CBookmarksNavPane::s_lpfnlGenericBtnProc = NULL; //WNDPROC CBookmarksNavPane::s_lpfnlGenericKeyboardProc = NULL ; /////////////////////////////////////////////////////////// // // Non-Member helper functions. // // Convert a rect from screen to client. void ScreenRectToClientRect(HWND hWnd, /*in/out*/ RECT* prect) ; /////////////////////////////////////////////////////////// // // Construction // /////////////////////////////////////////////////////////// // // CBookmarksNavPane(); // CBookmarksNavPane::CBookmarksNavPane(CHHWinType* pWinType) : m_hWnd(NULL), m_hfont(NULL), m_padding(2), // padding to put around the window m_pWinType(pWinType), m_pszCurrentUrl(NULL), m_bChanged(false) { ASSERT(pWinType) ; m_pTitleCollection = pWinType->m_phmData->m_pTitleCollection; ASSERT(m_pTitleCollection); m_NavTabPos = pWinType->tabpos ; } /////////////////////////////////////////////////////////// // // ~CBookmarksNavPane // CBookmarksNavPane::~CBookmarksNavPane() { //--- Persist Keywords in combo SaveBookmarks() ; //--- Empty the listview. int items = ListView_GetItemCount(m_aDlgItems[c_TopicsList].m_hWnd) ; if (items > 0) { // Iterate through each item get its size. for (int i = 0 ; i < items ; i++) { TCHAR* pUrl = GetUrl(i) ; ASSERT(pUrl) ; if (pUrl) { // Delete the attached url. delete [] pUrl ; } } // Delete all of the items W_ListView_DeleteAllItems(m_aDlgItems[c_TopicsList].m_hWnd) ; } //--- CleanUp if (m_hfont) { ::DeleteObject(m_hfont); } if (m_hWnd) { ::DestroyWindow(m_hWnd) ; } if (m_pszCurrentUrl) { delete m_pszCurrentUrl ; } //Don't free m_pTitleCollection } /////////////////////////////////////////////////////////// // // INavUI Interface functions. // /////////////////////////////////////////////////////////// // // Create // BOOL CBookmarksNavPane::Create(HWND hwndParent) { bool bReturn = false ; if (m_hWnd) { return true ; } // ---Create the dialog. bool bUnicode = true; if (! (m_hWnd = CreateDialogParamW( _Module.GetResourceInstance(), MAKEINTRESOURCEW(IDPAGE_TAB_BOOKMARKS), hwndParent, s_DialogProc, reinterpret_cast(this))) ) // Pass over the this pointer. { bUnicode = FALSE; if (! (m_hWnd = CreateDialogParamA( _Module.GetResourceInstance(), MAKEINTRESOURCEA(IDPAGE_TAB_BOOKMARKS), hwndParent, s_DialogProc, reinterpret_cast(this))) ) // Pass over the this pointer. return FALSE; } //--- Initialize the DlgItem Array. InitDlgItemArray() ; //--- Initialize the bookmarks list // Setup the columnsin the listview ; LV_COLUMNW column; column.mask = LVCF_FMT | LVCF_WIDTH; column.cx = 1500; //TODO FIX column.fmt = LVCFMT_LEFT; //column.iSubItem = 0; W_EnableUnicode(m_aDlgItems[c_TopicsList].m_hWnd, W_ListView); W_ListView_InsertColumn(m_aDlgItems[c_TopicsList].m_hWnd, 0, &column ); // Sub-class the list view if (s_lpfnlListViewWndProc == NULL) { s_lpfnlListViewWndProc = W_GetWndProc(m_aDlgItems[c_TopicsList].m_hWnd, bUnicode); } W_SubClassWindow(m_aDlgItems[c_TopicsList].m_hWnd, reinterpret_cast(s_ListViewProc), bUnicode); SETTHIS(m_aDlgItems[c_TopicsList].m_hWnd); //--- Initialize the Current Topic Edit Control // Limit the amount of text which can be typed in. Edit_LimitText(m_aDlgItems[c_CurrentTopicEdit].m_hWnd, MAX_PATH-1) ; // Subclass the keyword combo so that we can process the keys if (s_lpfnlCurrentTopicEditProc == NULL) { s_lpfnlCurrentTopicEditProc = W_GetWndProc(m_aDlgItems[c_CurrentTopicEdit].m_hWnd, bUnicode); } W_SubClassWindow(m_aDlgItems[c_CurrentTopicEdit].m_hWnd, reinterpret_cast(s_CurrentTopicEditProc), bUnicode); SETTHIS(m_aDlgItems[c_CurrentTopicEdit].m_hWnd); //--- Subclass all of the buttons // Start with the StartSearch button ; if (s_lpfnlGenericBtnProc == NULL) { s_lpfnlGenericBtnProc = W_GetWndProc(m_aDlgItems[c_DeleteBtn].m_hWnd, bUnicode); } W_SubClassWindow(m_aDlgItems[c_DeleteBtn].m_hWnd, reinterpret_cast(s_GenericBtnProc), bUnicode); SETTHIS(m_aDlgItems[c_DeleteBtn].m_hWnd); // Bitmap btn W_SubClassWindow(m_aDlgItems[c_DisplayBtn].m_hWnd, reinterpret_cast(s_GenericBtnProc), bUnicode); SETTHIS(m_aDlgItems[c_DisplayBtn].m_hWnd); // c_DisplayBtn W_SubClassWindow(m_aDlgItems[c_AddBookmarkBtn].m_hWnd, reinterpret_cast(s_GenericBtnProc), bUnicode); SETTHIS(m_aDlgItems[c_AddBookmarkBtn].m_hWnd); #if 0 //--- Set the font. This will fix some dbcs issues. for (int i = 0 ; i < c_NumDlgItems ; i++) { SendMessage(m_aDlgItems[i].m_hWnd, WM_SETFONT, (WPARAM) GetFont(), FALSE); } #endif SendMessage(m_aDlgItems[c_CurrentTopicEdit].m_hWnd, WM_SETFONT, (WPARAM) GetFont(), FALSE); SendMessage(m_aDlgItems[c_TopicsList].m_hWnd, WM_SETFONT, (WPARAM) GetAccessableContentFont(), FALSE); //--- Fill the combobox with persisted data. LoadBookmarks() ; // Set the focus to the appropriate control. SetDefaultFocus() ; //TODO: Fix return true; } /////////////////////////////////////////////////////////// // // OnCommand // LRESULT CBookmarksNavPane::OnCommand(HWND hwnd, UINT id, UINT NotifyCode, LPARAM lParam) { switch(NotifyCode) { case BN_CLICKED: switch(id) { case IDC_BOOKMARKS_DELETE_BTN: OnDelete() ; break; case IDC_BOOKMARKS_DISPLAY_BTN: OnDisplay() ; break ; case IDC_BOOKMARKS_ADDBOOKMARK_BTN: OnAddBookmark(); break; case IDC_BOOKMARKS_EDIT_BTN: OnEdit() ; break; default: return 0 ; } return 1 ; } return 0 ; } /////////////////////////////////////////////////////////// // // ResizeWindow // void CBookmarksNavPane::ResizeWindow() { ASSERT(::IsValidWindow(m_hWnd)) ; // Resize to fit the client area of the parent. HWND hwndParent = GetParent(m_hWnd) ; ASSERT(::IsValidWindow(hwndParent)) ; //--- Get the size of the window RECT rcParent; GetParentSize(&rcParent, hwndParent, m_padding, m_NavTabPos); //--- Move and size the dialog box itself. ::SetWindowPos( m_hWnd, NULL, rcParent.left, rcParent.top, rcParent.right-rcParent.left, rcParent.bottom-rcParent.top, SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOREDRAW); //---Fix the painting bugs. However, this is a little on the flashy side. ::InvalidateRect(m_hWnd, NULL, TRUE) ; RECT rcDlg; ::GetClientRect(m_hWnd, &rcDlg) ; //--- Now position each control within this space. for (int i = 0 ; i < c_NumDlgItems ; i++) { // Get Current Settings. int X = m_aDlgItems[i].m_rectCur.left; int Y = m_aDlgItems[i].m_rectCur.top; int CX = m_aDlgItems[i].m_rectCur.right - m_aDlgItems[i].m_rectCur.left; int CY = m_aDlgItems[i].m_rectCur.bottom - m_aDlgItems[i].m_rectCur.top; bool bChanged = false ; //--- RIGHT JUSTIFICATION if (m_aDlgItems[i].m_JustifyH == Justify::Right) { int NewX = rcDlg.right-m_aDlgItems[i].m_iOffsetH ; // subtract the offset int MinX = m_aDlgItems[i].m_rectMin.left; if (NewX < MinX) { NewX = MinX; // Don't go below min. } if (X != NewX) { X = NewX ; // Update the current setting. bChanged = true ; } } //--- BOTTOM JUSTIFICATION if (m_aDlgItems[i].m_JustifyV == Justify::Bottom) { int NewY = rcDlg.bottom - m_aDlgItems[i].m_iOffsetV; int MinY = m_aDlgItems[i].m_rectMin.top ; if (NewY < MinY) { NewY = MinY ; } if (Y != NewY) { Y = NewY ; // Update Setting. bChanged = true ; } } //--- HORIZONTAL GROWING if (m_aDlgItems[i].m_bGrowH) { int MaxCX = m_aDlgItems[i].m_rectMax.right - m_aDlgItems[i].m_rectMax.left ; int MinCX = m_aDlgItems[i].m_rectMin.right - m_aDlgItems[i].m_rectMin.left ; int MinCY = m_aDlgItems[i].m_rectMin.bottom - m_aDlgItems[i].m_rectMin.top ; int NewRight = rcDlg.right - m_aDlgItems[i].m_iPadH ; int NewCX = NewRight - m_aDlgItems[i].m_rectMin.left; if (NewCX < MinCX) { NewCX = MinCX; } else if ((!m_aDlgItems[i].m_bIgnoreMax) && NewCX > MaxCX) { NewCX = MaxCX ; } if (CX != NewCX) { CX = NewCX ; // Update Current ; bChanged = true ; } } //--- VERTICAL GROWING if (m_aDlgItems[i].m_bGrowV) { int MaxCY = m_aDlgItems[i].m_rectMax.bottom - m_aDlgItems[i].m_rectMax.top; int MinCY = m_aDlgItems[i].m_rectMin.bottom - m_aDlgItems[i].m_rectMin.top ; int MinCX = m_aDlgItems[i].m_rectMin.right - m_aDlgItems[i].m_rectMin.left; int NewBottom = rcDlg.bottom - m_aDlgItems[i].m_iPadV ; int NewCY = NewBottom - m_aDlgItems[i].m_rectMin.top; if (NewCY < MinCY) { NewCY = MinCY; } else if ((!m_aDlgItems[i].m_bIgnoreMax) && NewCY > MaxCY) { NewCY = MaxCY ; } if (CY != NewCY) { CY = NewCY ; bChanged = true ; } } if (bChanged) { m_aDlgItems[i].m_rectCur.left = X ; m_aDlgItems[i].m_rectCur.top = Y ; m_aDlgItems[i].m_rectCur.right = X + CX ; m_aDlgItems[i].m_rectCur.bottom = Y + CY ; ::SetWindowPos(m_aDlgItems[i].m_hWnd, NULL, X, Y, CX, CY, SWP_NOZORDER | SWP_NOOWNERZORDER /*| SWP_NOREDRAW*/); // If we have to change the size of the results list, lets change the size of the columns. /* if (i == c_ResultsList) { m_plistview->SizeColumns() ; } */ } } } /////////////////////////////////////////////////////////// // // HideWindow // void CBookmarksNavPane::HideWindow() { if (::IsValidWindow(m_hWnd)) { ::ShowWindow(m_hWnd, SW_HIDE) ; } } /////////////////////////////////////////////////////////// // // ShowWindow // void CBookmarksNavPane::ShowWindow() { if (::IsValidWindow(m_hWnd)) { // Turn the dialog items on/off ShowDlgItemsEnabledState() ; // Show the dialog window. ::ShowWindow(m_hWnd, SW_SHOW) ; } } /////////////////////////////////////////////////////////// // // SetPadding // void CBookmarksNavPane::SetPadding(int pad) { m_padding = pad; } /////////////////////////////////////////////////////////// // // SetTabPos // void CBookmarksNavPane::SetTabPos(int tabpos) { m_NavTabPos = tabpos; } /////////////////////////////////////////////////////////// // // SetDefaultFocus --- Set focus to the most expected control, usually edit combo. // void CBookmarksNavPane::SetDefaultFocus() { if (::IsValidWindow(m_aDlgItems[c_TopicsList].m_hWnd)) { BookmarkDlgItemInfoIndex ctrl ; int items = W_ListView_GetItemCount(m_aDlgItems[c_TopicsList].m_hWnd) ; if (items > 0) { // Set focus to the topics list if we have any entries in it. ctrl = c_TopicsList ; // Set the focus if nothing selected. if (GetSelectedItem() < 0) { W_ListView_SetItemState(m_aDlgItems[c_TopicsList].m_hWnd, 0, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED) ; } } else { // Set focus to the edit control if the topic listis empty. ctrl = c_CurrentTopicEdit ; } SetFocus(m_aDlgItems[ctrl].m_hWnd) ; } } /////////////////////////////////////////////////////////// // // ProcessMenuChar --- Process accelerator keys. // bool CBookmarksNavPane::ProcessMenuChar(HWND hwndParent, int ch) { return ::ProcessMenuChar(this, hwndParent, m_aDlgItems, c_NumDlgItems, ch) ; } /////////////////////////////////////////////////////////// // // OnNotify --- Process WM_NOTIFY messages. Used by embedded Tree and List view controls. // LRESULT CBookmarksNavPane::OnNotify(HWND hwnd, WPARAM idCtrl, LPARAM lParam) { switch(idCtrl) { case IDC_BOOKMARKS_TOPICS_LISTVIEW: if (::IsValidWindow(m_aDlgItems[c_TopicsList].m_hWnd)) { return ListViewMsg(m_aDlgItems[c_TopicsList].m_hWnd, (NM_LISTVIEW*) lParam); } break ; default: //return DefDlgProc(m_hWnd, WM_NOTIFY, idCtrl, lParam); return 0 ; } return 0 ; } /////////////////////////////////////////////////////////// // // OnDrawItem --- Process WM_DRAWITEM messages. // void CBookmarksNavPane::OnDrawItem(UINT id, LPDRAWITEMSTRUCT pdis) { } /////////////////////////////////////////////////////////// // // Seed --- Seed the nav ui with a search term or keyword. // void CBookmarksNavPane::Seed(LPCSTR pszSeed) { } /////////////////////////////////////////////////////////// // // Synchronize // BOOL CBookmarksNavPane::Synchronize(PSTR pNotUsed, CTreeNode* pNotUsed2) { if (pNotUsed == NULL && pNotUsed2 == NULL) { FillCurrentTopicEdit() ; return TRUE ; } else { return FALSE ; } } /////////////////////////////////////////////////////////// // // Helper Functions. // /////////////////////////////////////////////////////////// // // InitDlgItemArray // void CBookmarksNavPane::InitDlgItemArray() { RECT rectCurrent ; RECT rectDlg ; ::GetClientRect(m_hWnd, &rectDlg) ; //--- Setup the dlg array for each control. //--- Topics ListView int i = c_TopicsList; m_aDlgItems[i].m_hWnd = ::GetDlgItem(m_hWnd, IDC_BOOKMARKS_TOPICS_LISTVIEW) ; ::GetWindowRect(m_aDlgItems[i].m_hWnd, &rectCurrent) ; // Get screen coordinates. ScreenRectToClientRect(m_hWnd, &rectCurrent); // Convert to client DWORD_PTR dwCurrentExtendedStyles = GetWindowLongPtr(m_aDlgItems[i].m_hWnd, GWL_EXSTYLE); SetWindowLongPtr(m_aDlgItems[i].m_hWnd, GWL_EXSTYLE, dwCurrentExtendedStyles | g_RTL_Mirror_Style); m_aDlgItems[i].m_id = IDC_BOOKMARKS_TOPICS_LISTVIEW; m_aDlgItems[i].m_accelkey = (CHAR)GetAcceleratorKey(m_hWnd, IDC_BOOKMARKS_TOPICS_STATIC); // No accelerator. m_aDlgItems[i].m_Type = ItemInfo::Generic; m_aDlgItems[i].m_bIgnoreEnabled = TRUE ; //m_aDlgItems[i].m_bEnabled; // Is the control enabled? m_aDlgItems[i].m_bIgnoreMax = TRUE ; // Ignore the Max parameter. m_aDlgItems[i].m_bGrowH = TRUE; // Grow Horizontally. m_aDlgItems[i].m_bGrowV = TRUE ; // Grow Vertically. m_aDlgItems[i].m_JustifyV = Justify::Top; // Do we stick to the top or the bottom. //m_aDlgItems[i].m_iOffsetV = ; // Distance from our justification point. m_aDlgItems[i].m_JustifyH = Justify::Left; // Do we stick to the right or the left //m_aDlgItems[i].m_iOffsetH = rectDlg.right - rectCurrent.left; m_aDlgItems[i].m_iPadH = rectDlg.right - rectCurrent.right; // Maintain same distance. If someone to the right grows we are broken. m_aDlgItems[i].m_iPadV = rectDlg.bottom - rectCurrent.bottom; m_aDlgItems[i].m_rectMin = rectCurrent; m_aDlgItems[i].m_rectCur = rectCurrent; //m_aDlgItems[i].m_rectMax ; // Max size. //--- Delete Button i = c_DeleteBtn; m_aDlgItems[i].m_hWnd = ::GetDlgItem(m_hWnd, IDC_BOOKMARKS_DELETE_BTN) ; ::GetWindowRect(m_aDlgItems[i].m_hWnd, &rectCurrent) ; // Get screen coordinates. ScreenRectToClientRect(m_hWnd, &rectCurrent); // Convert to client m_aDlgItems[i].m_id = IDC_BOOKMARKS_DELETE_BTN; m_aDlgItems[i].m_accelkey = (CHAR)GetAcceleratorKey(m_aDlgItems[i].m_hWnd) ; m_aDlgItems[i].m_Type = ItemInfo::Button; m_aDlgItems[i].m_bIgnoreEnabled = FALSE; m_aDlgItems[i].m_bEnabled = FALSE; // Is the control enabled? m_aDlgItems[i].m_bIgnoreMax = TRUE ; // Ignore the Max parameter. m_aDlgItems[i].m_bGrowH = FALSE; // Grow Horizontally. m_aDlgItems[i].m_bGrowV = FALSE ; // Grow Vertically. m_aDlgItems[i].m_JustifyV = Justify::Bottom; // Do we stick to the top or the bottom. m_aDlgItems[i].m_iOffsetV = rectDlg.bottom - rectCurrent.top ; // Distance from our justification point. m_aDlgItems[i].m_JustifyH = Justify::Right; // Do we stick to the right or the left m_aDlgItems[i].m_iOffsetH = rectDlg.right - rectCurrent.left; //m_aDlgItems[i].m_iPadH = ; // Right Horizontal Padding. //m_aDlgItems[i].m_iPadV = ; // Bottom Vertical Padding. m_aDlgItems[i].m_rectMin = rectCurrent; m_aDlgItems[i].m_rectCur = rectCurrent; //m_aDlgItems[i].m_rectMax ; // Max size. //--- Display Button i = c_DisplayBtn; m_aDlgItems[i].m_hWnd = ::GetDlgItem(m_hWnd, IDC_BOOKMARKS_DISPLAY_BTN) ; ::GetWindowRect(m_aDlgItems[i].m_hWnd, &rectCurrent) ; // Get screen coordinates. ScreenRectToClientRect(m_hWnd, &rectCurrent); // Convert to client m_aDlgItems[i].m_id = IDC_BOOKMARKS_DISPLAY_BTN; m_aDlgItems[i].m_accelkey = (CHAR)GetAcceleratorKey(m_aDlgItems[i].m_hWnd) ; m_aDlgItems[i].m_Type = ItemInfo::Button; m_aDlgItems[i].m_bIgnoreEnabled = FALSE; m_aDlgItems[i].m_bEnabled = FALSE; // Is the control enabled? m_aDlgItems[i].m_bIgnoreMax = TRUE ; // Ignore the Max parameter. m_aDlgItems[i].m_bGrowH = FALSE; // Grow Horizontally. m_aDlgItems[i].m_bGrowV = FALSE ; // Grow Vertically. m_aDlgItems[i].m_JustifyV = Justify::Bottom; // Do we stick to the top or the bottom. m_aDlgItems[i].m_iOffsetV = rectDlg.bottom - rectCurrent.top ; // Distance from our justification point. m_aDlgItems[i].m_JustifyH = Justify::Right; // Do we stick to the right or the left m_aDlgItems[i].m_iOffsetH = rectDlg.right - rectCurrent.left; //m_aDlgItems[i].m_iPadH = ; // Right Horizontal Padding. //m_aDlgItems[i].m_iPadV = ; // Bottom Vertical Padding. m_aDlgItems[i].m_rectMin = rectCurrent; m_aDlgItems[i].m_rectCur = rectCurrent; //m_aDlgItems[i].m_rectMax ; // Max size. //--- Current Topics Static i = c_CurrentTopicStatic; m_aDlgItems[i].m_hWnd = ::GetDlgItem(m_hWnd, IDC_BOOKMARKS_CURRENTTOPIC_STATIC) ; ::GetWindowRect(m_aDlgItems[i].m_hWnd, &rectCurrent) ; // Get screen coordinates. ScreenRectToClientRect(m_hWnd, &rectCurrent); // Convert to client m_aDlgItems[i].m_id = IDC_BOOKMARKS_CURRENTTOPIC_STATIC; m_aDlgItems[i].m_accelkey = 0 ; m_aDlgItems[i].m_Type = ItemInfo::Generic; m_aDlgItems[i].m_bIgnoreEnabled = TRUE ; //m_aDlgItems[i].m_bEnabled; // Is the control enabled? m_aDlgItems[i].m_bIgnoreMax = TRUE ; // Ignore the Max parameter. m_aDlgItems[i].m_bGrowH = FALSE; // Grow Horizontally. m_aDlgItems[i].m_bGrowV = FALSE ; // Grow Vertically. m_aDlgItems[i].m_JustifyV = Justify::Bottom; // Do we stick to the top or the bottom. m_aDlgItems[i].m_iOffsetV = rectDlg.bottom - rectCurrent.top ; // Distance from our justification point. m_aDlgItems[i].m_JustifyH = Justify::Left; // Do we stick to the right or the left //m_aDlgItems[i].m_iOffsetH = //m_aDlgItems[i].m_iPadH = ; // Right Horizontal Padding. //m_aDlgItems[i].m_iPadV = ; // Bottom Vertical Padding. m_aDlgItems[i].m_rectMin = rectCurrent; m_aDlgItems[i].m_rectCur = rectCurrent; //m_aDlgItems[i].m_rectMax ; // Max size. //--- Current Topics Edit control i = c_CurrentTopicEdit; m_aDlgItems[i].m_hWnd = ::GetDlgItem(m_hWnd, IDC_BOOKMARKS_CURRENTTOPIC_EDIT) ; ::GetWindowRect(m_aDlgItems[i].m_hWnd, &rectCurrent) ; // Get screen coordinates. ScreenRectToClientRect(m_hWnd, &rectCurrent); // Convert to client dwCurrentExtendedStyles = GetWindowLongPtr(m_aDlgItems[i].m_hWnd, GWL_EXSTYLE); SetWindowLongPtr(m_aDlgItems[i].m_hWnd, GWL_EXSTYLE, dwCurrentExtendedStyles | g_RTL_Style); m_aDlgItems[i].m_id = IDC_BOOKMARKS_CURRENTTOPIC_EDIT; m_aDlgItems[i].m_accelkey = (CHAR)GetAcceleratorKey(m_hWnd, IDC_BOOKMARKS_CURRENTTOPIC_STATIC); m_aDlgItems[i].m_Type = ItemInfo::Generic; m_aDlgItems[i].m_bIgnoreEnabled = TRUE ; //m_aDlgItems[i].m_bEnabled; // Is the control enabled? m_aDlgItems[i].m_bIgnoreMax = TRUE ; // Ignore the Max parameter. m_aDlgItems[i].m_bGrowH = TRUE; // Grow Horizontally. m_aDlgItems[i].m_bGrowV = FALSE ; // Grow Vertically. m_aDlgItems[i].m_JustifyV = Justify::Bottom; // Do we stick to the top or the bottom. m_aDlgItems[i].m_iOffsetV = rectDlg.bottom - rectCurrent.top ; // Distance from our justification point. m_aDlgItems[i].m_JustifyH = Justify::Left; // Do we stick to the right or the left //m_aDlgItems[i].m_iOffsetH = rectDlg.right - rectCurrent.left; m_aDlgItems[i].m_iPadH = rectDlg.right - rectCurrent.right; // Maintain same distance. If someone to the right grows we are broken. //m_aDlgItems[i].m_iPadV = ; // Bottom Vertical Padding. m_aDlgItems[i].m_rectMin = rectCurrent; m_aDlgItems[i].m_rectCur = rectCurrent; //m_aDlgItems[i].m_rectMax ; // Max size. //--- Add Button i = c_AddBookmarkBtn ; m_aDlgItems[i].m_hWnd = ::GetDlgItem(m_hWnd, IDC_BOOKMARKS_ADDBOOKMARK_BTN) ; ::GetWindowRect(m_aDlgItems[i].m_hWnd, &rectCurrent) ; // Get screen coordinates. ScreenRectToClientRect(m_hWnd, &rectCurrent); // Convert to client m_aDlgItems[i].m_id = IDC_BOOKMARKS_ADDBOOKMARK_BTN; m_aDlgItems[i].m_accelkey = (CHAR)GetAcceleratorKey(m_aDlgItems[i].m_hWnd) ; m_aDlgItems[i].m_Type = ItemInfo::Button; m_aDlgItems[i].m_bIgnoreEnabled = TRUE ; //m_aDlgItems[i].m_bEnabled; // Is the control enabled? m_aDlgItems[i].m_bIgnoreMax = TRUE ; // Ignore the Max parameter. m_aDlgItems[i].m_bGrowH = FALSE; // Grow Horizontally. m_aDlgItems[i].m_bGrowV = FALSE ; // Grow Vertically. m_aDlgItems[i].m_JustifyV = Justify::Bottom; // Do we stick to the top or the bottom. m_aDlgItems[i].m_iOffsetV = rectDlg.bottom - rectCurrent.top ; // Distance from our justification point. m_aDlgItems[i].m_JustifyH = Justify::Right; // Do we stick to the right or the left m_aDlgItems[i].m_iOffsetH =rectDlg.right - rectCurrent.left; //m_aDlgItems[i].m_iPadH = ; // Right Horizontal Padding. //m_aDlgItems[i].m_iPadV = ; // Bottom Vertical Padding. m_aDlgItems[i].m_rectMin = rectCurrent; m_aDlgItems[i].m_rectCur = rectCurrent; //m_aDlgItems[i].m_rectMax ; // Max size. } /////////////////////////////////////////////////////////// // // SetEnabledState // void CBookmarksNavPane::ShowDlgItemsEnabledState() { // Enable/Disable all the controls for (int i = 0 ; i < c_NumDlgItems ; i++) { if (!m_aDlgItems[i].m_bIgnoreEnabled && ::IsValidWindow(m_aDlgItems[i].m_hWnd)) { EnableWindow(m_aDlgItems[i].m_hWnd, m_aDlgItems[i].m_bEnabled) ; } } } /////////////////////////////////////////////////////////// // // EnableDlgItem // void CBookmarksNavPane::EnableDlgItem(BookmarkDlgItemInfoIndex index, bool bEnable) { ASSERT(index >= 0 && index < c_NumDlgItems) ; if (!m_aDlgItems[index].m_bIgnoreEnabled) { // Are we enabled or not? m_aDlgItems[index].m_bEnabled = bEnable ; // Do it for real. if (::IsValidWindow(m_aDlgItems[index].m_hWnd)) { EnableWindow(m_aDlgItems[index].m_hWnd, bEnable) ; } } } /////////////////////////////////////////////////////////// // // SaveBookmarks --- Persists the bookmars to the storage // // The bookmarks are stored using the following format: // Bookmarks // \v1 - Version. // \Count - Number of bookmarks written. // \0 - First bookmark. // \Topic - Topic Unicode String // \Url - Url Unicode String // \1 - Second bookmark. // ... // \(count-1) // void CBookmarksNavPane::SaveBookmarks() { // Also save the bookmarks, if they have changed. if (!Changed()) { return ; } // Keep track of the number of bookmarks written. int cWritten = 0 ; // Buffer for path to the state folder. char statepath[64] ; // Get the state pointer. CState* pstate = m_pTitleCollection->GetState(); ASSERT(pstate) ; // Are there any keywords to save. int items = W_ListView_GetItemCount(m_aDlgItems[c_TopicsList].m_hWnd) ; if (items > 0) { // Limit the number. I hate limiting the number, but its much more robust. if (items > c_MaxBookmarks) { items = c_MaxBookmarks ; } // Buffer for retrieving the text. WCHAR Topic[MAX_URL] ; // Iterate through the items. for (int i = 0 ; i < items ; i++) { TCHAR* pUrl = NULL ; if (GetTopicAndUrl(i, Topic, sizeof(Topic), &pUrl)) { //--- Write out topic. // Construct the path. wsprintf(statepath, "%s\\%d\\%s", c_PersistFolder, cWritten, c_TopicFolder); if (SUCCEEDED(pstate->Open(statepath, STGM_WRITE))) { DWORD cb = (wcslen(Topic)+1)*sizeof(wchar_t) ; DWORD dwResult = pstate->Write(Topic, cb); pstate->Close(); // Is result okay? if (cb == dwResult) { //--- Write out the URL. // Convert to unicode. CWStr url(pUrl) ; ASSERT(url.pw) ; // Construt the path. wsprintf(statepath, "%s\\%d\\%s", c_PersistFolder, cWritten, c_UrlFolder); // Write out. if (SUCCEEDED(pstate->Open(statepath, STGM_WRITE))) { cb = (wcslen(url.pw)+1)*sizeof(wchar_t) ; dwResult = pstate->Write(url.pw, cb); pstate->Close(); // Check result. if (cb == dwResult) { // We have been successful. So Increment the count. cWritten++ ; } } } } } //if } // for } // if items // How many entries are currently stored. int StoredCount = 0; if (SUCCEEDED(pstate->Open(c_CountFolder, STGM_READ))) { DWORD cbReadIn = 0 ; pstate->Read(&StoredCount , sizeof(StoredCount), &cbReadIn) ; pstate->Close() ; if (cbReadIn != sizeof(StoredCount)) { // Assume that we don't have any stored. StoredCount = 0 ; } } // Delete the extra entries. if (StoredCount > cWritten) { // Delete extra entries. for(int j = cWritten ; j < StoredCount ; j++) { // Remove the URL folder. wsprintf(statepath, "%s\\%d\\%s", c_PersistFolder, j, c_UrlFolder); if (SUCCEEDED(pstate->Open(statepath, STGM_READ))) { HRESULT hr = pstate->Delete() ; ASSERT(SUCCEEDED(hr)) ; pstate->Close() ; } // Remove the topic folder. wsprintf(statepath, "%s\\%d\\%s", c_PersistFolder, j, c_TopicFolder); if (SUCCEEDED(pstate->Open(statepath, STGM_WRITE))) { HRESULT hr = pstate->Delete() ; ASSERT(SUCCEEDED(hr)) ; pstate->Close() ; } // Remove branch. wsprintf(statepath, "%s\\%d", c_PersistFolder, j); if (SUCCEEDED(pstate->Open(statepath, STGM_WRITE))) { HRESULT hr = pstate->Delete() ; ASSERT(SUCCEEDED(hr)) ; pstate->Close() ; } } } // Write out the count. if (cWritten >= 0) // We may have deleted everything, so count can be zero. { // Write out the new count. if (SUCCEEDED(pstate->Open(c_CountFolder, STGM_WRITE))) { DWORD cb = pstate->Write(&cWritten, sizeof(cWritten)); ASSERT(cb == sizeof(cWritten)) ; // TODO: Handle error. pstate->Close() ; // Reset dirty flag ; SetChanged(false) ; } } else { //TODO: Erase everything. That is there. } } /////////////////////////////////////////////////////////// // // LoadBookmarks - Loads the results list from the storage // void CBookmarksNavPane::LoadBookmarks() { CState* pstate = m_pTitleCollection->GetState(); if (SUCCEEDED(pstate->Open(c_CountFolder, STGM_READ))) { // Read in the topics stored. DWORD cbReadIn = 0 ; int StoredCount = 0; pstate->Read(&StoredCount , sizeof(StoredCount), &cbReadIn) ; pstate->Close() ; // Did we get a reasonable number? if (cbReadIn == sizeof(StoredCount) && StoredCount > 0 && StoredCount < c_MaxBookmarks) // We check the max here just to sure we have reasonable numbers. { // Buffer for path to the state folder. char statepath[64] ; WCHAR buffer[MAX_URL] ; // Now let's read them in. for (int i=0 ; i < StoredCount ; i++) { //--- Read in the URL. TCHAR* pUrl = NULL ; // Construct the path. wsprintf(statepath, "%s\\%d\\%s", c_PersistFolder, i, c_UrlFolder); // Open Topic in. if (SUCCEEDED(pstate->Open(statepath, STGM_READ))) { // Read it into the buffer. DWORD cb = NULL ; HRESULT hr = pstate->Read(&buffer, sizeof(buffer), &cb); pstate->Close(); // Check result. if (SUCCEEDED(hr)) { // Convert from unicode. CStr strUrl(buffer) ; ASSERT(strUrl.psz) ; //--- Read in the topic. // Construct the path. wsprintf(statepath, "%s\\%d\\%s", c_PersistFolder, i, c_TopicFolder); if (SUCCEEDED(pstate->Open(statepath, STGM_READ))) { cb = NULL; hr = pstate->Read(&buffer, sizeof(buffer), &cb); pstate->Close(); if (SUCCEEDED(hr)) { //--- Save the URL. TCHAR* pszUrl = new TCHAR[strUrl.strlen()+1] ; _tcscpy(pszUrl, strUrl.psz) ; //--- Add the string to the listview. LV_ITEMW item; item.mask = LVIF_TEXT | LVIF_PARAM ; //| LVIF_STATE; item.iImage = 0; //item.state = LVIS_FOCUSED | LVIS_SELECTED; //item.stateMask = LVIS_FOCUSED | LVIS_SELECTED; item.iItem = 0 ; item.iSubItem = 0; item.lParam = (LPARAM)pszUrl; item.pszText = buffer; W_ListView_InsertItem( m_aDlgItems[c_TopicsList].m_hWnd, &item ); } } } } // if --- opened topic. } // for // We haven't changed. SetChanged(false) ; } //if --- count valid } //if --- Can read count } /////////////////////////////////////////////////////////// // // FillCurrentTopicEdit // void CBookmarksNavPane::FillCurrentTopicEdit() { ASSERT(m_pWinType && m_pWinType->m_pCIExpContainer && m_pWinType->m_pCIExpContainer->m_pWebBrowserApp) ; ASSERT(m_pTitleCollection) ; //--- Prepare to be re-entered! // Delete the current URL. if (m_pszCurrentUrl) { delete m_pszCurrentUrl ; m_pszCurrentUrl = NULL ; } // Clear out the edit control. W_SetWindowText(m_aDlgItems[c_CurrentTopicEdit].m_hWnd, L"") ; //--- Get to work. CStr url ; if (m_pWinType && m_pWinType->m_pCIExpContainer && m_pWinType->m_pCIExpContainer->m_pWebBrowserApp) { // Get the URL of the current topic. m_pWinType->m_pCIExpContainer->m_pWebBrowserApp->GetLocationURL(&url); //Urg there is no error return!!! if (!url.IsEmpty()) { //--- Save the URL before we normalize it. m_pszCurrentUrl = new TCHAR[url.strlen()+1] ; _tcscpy(m_pszCurrentUrl,url.psz) ; // Nomalize the URL NormalizeUrlInPlace(url) ; // Use the url to get a CExTitle pointer. bool bFoundTitle = false; // Did we find a title? CExTitle *pTitle = NULL ; HRESULT hr = m_pTitleCollection->URL2ExTitle(m_pszCurrentUrl, &pTitle); if (SUCCEEDED(hr) && pTitle) { // Use the pTitle to get the topic number. //TOC_TOPIC topic ; // Don't need DWORD topicnumber; hr = pTitle->URL2Topic(url, NULL/*&topic*/, &topicnumber); if (SUCCEEDED(hr)) { // Now that we have a topic number we can get the location string. WCHAR wszCurrentTopic[MAX_PATH] ; hr = pTitle->GetTopicName(topicnumber, wszCurrentTopic, (MAX_PATH/2)) ; if (SUCCEEDED(hr)) { // Yea, we finally have a location W_SetWindowText(m_aDlgItems[c_CurrentTopicEdit].m_hWnd, wszCurrentTopic) ; // We have found the title! bFoundTitle = true ; } } } // We have not found the title. Maybe its a web site. if (!bFoundTitle) { ASSERT(m_pszCurrentUrl) ; // convert URL to wide... CWStr wurl(url) ; ASSERT(wurl.pw) ; // So put he normalized URL into the edit control. W_SetWindowText(m_aDlgItems[c_CurrentTopicEdit].m_hWnd, wurl.pw) ; } } } } /////////////////////////////////////////////////////////// // // Get the selected item // CBookmarksNavPane::GetSelectedItem() const { int indexSelected = -1 ; int selections = W_ListView_GetSelectedCount(m_aDlgItems[c_TopicsList].m_hWnd) ; if (selections > 0) { ASSERT(selections == 1) ; indexSelected = W_ListView_GetNextItem(m_aDlgItems[c_TopicsList].m_hWnd, -1, LVNI_SELECTED) ; } return indexSelected ; } /////////////////////////////////////////////////////////// // // Get the Url for the item // TCHAR* CBookmarksNavPane::GetUrl(int index) const { TCHAR* pReturn = NULL ; if ((index >= 0) && (index < W_ListView_GetItemCount(m_aDlgItems[c_TopicsList].m_hWnd))) { LV_ITEMW item ; item.mask = LVIF_PARAM; item.iItem = index; item.iSubItem = 0; item.lParam = NULL; W_ListView_GetItem(m_aDlgItems[c_TopicsList].m_hWnd, &item) ; pReturn = (TCHAR*)item.lParam ; } return pReturn ; } /////////////////////////////////////////////////////////// // // Get the URL and the Topic name. // bool CBookmarksNavPane::GetTopicAndUrl( int index, //[in] Index WCHAR* pTopicBuffer, //[in] Buffer for the topic. int TopicBufferSize, //[in] Size of the topic buffer. TCHAR** pUrl //[out] Pointer to Url. ) const { bool bReturn = false ; if ((index >= 0) && (index < W_ListView_GetItemCount(m_aDlgItems[c_TopicsList].m_hWnd))) { LV_ITEMW item ; item.mask = LVIF_PARAM | LVIF_TEXT ; item.iItem = index; item.iSubItem = 0; item.lParam = NULL ; item.pszText = pTopicBuffer; item.cchTextMax = TopicBufferSize ; if (W_ListView_GetItem(m_aDlgItems[c_TopicsList].m_hWnd, &item)) { *pUrl = (TCHAR*)item.lParam ; ASSERT(*pUrl) ; if (*pUrl) //TODO: Validate pTopicBuffer ; { bReturn = true; } } else { bReturn = false ; } } return bReturn ; } /////////////////////////////////////////////////////////// // // ContextMenu // void CBookmarksNavPane::ContextMenu(bool bUseCursor) { // Create the menu. HMENU hMenu = LoadMenu(_Module.GetResourceInstance(), MAKEINTRESOURCE(IDM_BOOKMARKS_OPTIONS_MENU)) ; ASSERT(hMenu) ; // Get the Popup Menu HMENU hPopupMenu = GetSubMenu(hMenu, 0) ; // Is an item selected? int bState ; int selection = GetSelectedItem() ; if (selection < 0) { // Nothing selected. bState = MF_GRAYED ; } else { bState = MF_ENABLED ; } // Set state of menu items. EnableMenuItem(hPopupMenu, IDC_BOOKMARKS_DELETE_BTN, MF_BYCOMMAND | bState) ; EnableMenuItem(hPopupMenu, IDC_BOOKMARKS_DISPLAY_BTN, MF_BYCOMMAND | bState ) ; EnableMenuItem(hPopupMenu, IDC_BOOKMARKS_EDIT_BTN, MF_BYCOMMAND | bState) ; // Always enabled. EnableMenuItem(hPopupMenu, IDC_BOOKMARKS_ADDBOOKMARK_BTN, MF_BYCOMMAND | MF_ENABLED) ; // Set the style of the menu. DWORD style = TPM_LEFTALIGN | TPM_TOPALIGN | TPM_NONOTIFY | TPM_RETURNCMD | TPM_RIGHTBUTTON; //--- Get the location to display the menu POINT pt ; if (bUseCursor) { // Use the mouse cursor position. GetCursorPos(&pt) ; } else { // Use the upper right of the client area. Probably invoked by shift-F10 RECT rc; GetClientRect(m_aDlgItems[c_TopicsList].m_hWnd, &rc) ; //REVIEW: Upper corner should always be 0,0. Remove? pt.x = rc.left; pt.y = rc.top ; ClientToScreen(m_aDlgItems[c_TopicsList].m_hWnd, &pt); } // Display the menu. int iCmd = TrackPopupMenuEx(hPopupMenu, style , pt.x, pt.y, m_hWnd, NULL) ; // Act on the item. if (iCmd != 0) { OnCommand(m_hWnd, iCmd, BN_CLICKED, NULL); } // Cleanup DestroyMenu(hMenu) ; } /////////////////////////////////////////////////////////// // // Message Handlers // /////////////////////////////////////////////////////////// // // OnDelete // void CBookmarksNavPane::OnDelete() { int indexSelected = GetSelectedItem() ; HWND hwndFocus = ::GetFocus(); BOOL bDeletedLast = FALSE; if (indexSelected >= 0) { TCHAR* pUrl = GetUrl(indexSelected) ; ASSERT(pUrl) ; if (pUrl) { // Delete the attached url. delete [] pUrl ; } // Delete the item BOOL b = W_ListView_DeleteItem(m_aDlgItems[c_TopicsList].m_hWnd, indexSelected) ; ASSERT(b) ; // Set changed flag. SetChanged() ; // Select the item below the one we just deleted. int items = W_ListView_GetItemCount(m_aDlgItems[c_TopicsList].m_hWnd) ; if (items > 0) { if (indexSelected >= items) { indexSelected = items-1 ; } // The following should never happen, but its better safe in beta2... if (indexSelected < 0) { ASSERT(indexSelected < 0) ; indexSelected = 0 ; } W_ListView_SetItemState(m_aDlgItems[c_TopicsList].m_hWnd, indexSelected, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED) ; } else bDeletedLast = TRUE; } if (bDeletedLast == TRUE) ::SetFocus(m_aDlgItems[c_AddBookmarkBtn].m_hWnd); else if (hwndFocus != m_aDlgItems[c_TopicsList].m_hWnd) ::SetFocus(hwndFocus); } /////////////////////////////////////////////////////////// // // OnDisplay // void CBookmarksNavPane::OnDisplay() { // Get the selected URL. TCHAR* pUrl = GetSelectedUrl() ; if (pUrl) { // Change to this URL. ChangeHtmlTopic(pUrl, m_hWnd, 0); } } /////////////////////////////////////////////////////////// // // OnAddBookmark // void CBookmarksNavPane::OnAddBookmark() { int len = W_GetTextLengthExact(m_aDlgItems[c_CurrentTopicEdit].m_hWnd) ; if (len > 0) { // Get the string from the edit control WCHAR* pCurrentTopicTitle = new WCHAR[len+1] ; W_GetWindowText(m_aDlgItems[c_CurrentTopicEdit].m_hWnd, pCurrentTopicTitle, len+1) ; //--- Copy the URL. ASSERT(m_pszCurrentUrl) ; TCHAR* pszUrl = new TCHAR[_tcslen(m_pszCurrentUrl)+1] ; _tcscpy(pszUrl, m_pszCurrentUrl) ; //--- Add the string to the listview. LV_ITEMW item; item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE; item.iImage = 0; item.state = LVIS_FOCUSED | LVIS_SELECTED; item.stateMask = LVIS_FOCUSED | LVIS_SELECTED; item.iItem = 0 ; item.iSubItem = 0; item.lParam = (LPARAM)pszUrl; item.pszText = pCurrentTopicTitle ; int i = W_ListView_InsertItem( m_aDlgItems[c_TopicsList].m_hWnd, &item ); //Setfocus to list view SetFocus(m_aDlgItems[c_TopicsList].m_hWnd) ; // Cleanup delete [] pCurrentTopicTitle ; // Set changed flag. SetChanged() ; } } /////////////////////////////////////////////////////////// // // OnEdit - Handles the edit menu item. // void CBookmarksNavPane::OnEdit() { // Edit the currently selected item. int selection = GetSelectedItem() ; if (selection >=0) { W_ListView_EditLabel(m_aDlgItems[c_TopicsList].m_hWnd, selection) ; // Set changed flag. SetChanged() ; } } /////////////////////////////////////////////////////////// // // OnTab - Handles pressing of the tab key. // void CBookmarksNavPane::OnTab(HWND hwndReceivedTab, BookmarkDlgItemInfoIndex /*index*/) { //if (index == c_NumDlgItems) --- caller doesn't know the index. ASSERT(::IsValidWindow(hwndReceivedTab)) ; //--- Is the shift key down? BOOL bPrevious = (GetKeyState(VK_SHIFT) < 0) ; { //--- Move to the next control . // Get the next tab item. HWND hWndNext = GetNextDlgTabItem(m_hWnd, hwndReceivedTab, bPrevious) ; // Set focus to it. ::SetFocus(hWndNext) ; } } /////////////////////////////////////////////////////////// // // OnArrow // void CBookmarksNavPane::OnArrow(HWND hwndReceivedTab, BookmarkDlgItemInfoIndex /*index*/, INT_PTR key) { //if (index == c_NumDlgItems) --- caller doesn't know the index. ASSERT(::IsValidWindow(hwndReceivedTab)) ; BOOL bPrevious = FALSE ; if (key == VK_LEFT || key == VK_UP) { bPrevious = TRUE ; } // Get the next tab item. HWND hWndNext = GetNextDlgGroupItem(m_hWnd, hwndReceivedTab, bPrevious) ; // Set focus to it. ::SetFocus(hWndNext) ; } /////////////////////////////////////////////////////////// // // OnReturn - Default handling of the return key. // bool CBookmarksNavPane::OnReturn(HWND hwndReceivedTab, BookmarkDlgItemInfoIndex /*index*/) { //if (index == c_NumDlgItems) --- caller doesn't know the index. // Do the default button action. // Always do a search topic, if its enabled. if (::IsWindowEnabled(m_aDlgItems[c_DisplayBtn].m_hWnd)) { OnDisplay(); return true ; } else { return false ; } } /////////////////////////////////////////////////////////// // // ListViewMsg // LRESULT CBookmarksNavPane::ListViewMsg(HWND hwnd, NM_LISTVIEW* lParam) { switch(lParam->hdr.code) { case NM_DBLCLK: case NM_RETURN: OnDisplay() ; break; case NM_RCLICK: ContextMenu() ; break ; case LVN_ITEMCHANGED: { bool bEnable = GetSelectedItem() >= 0 ; EnableDlgItem(c_DisplayBtn, bEnable) ; EnableDlgItem(c_DeleteBtn, bEnable) ; } break ; case LVN_BEGINLABELEDITA: case LVN_BEGINLABELEDITW: /* //ListView_GetEditControl(); //LimitText; */ return FALSE ; case LVN_ENDLABELEDITA: case LVN_ENDLABELEDITW: { LV_DISPINFOW* pDispInfo = (LV_DISPINFOW*)lParam ; if (pDispInfo->item.iItem != -1 && pDispInfo->item.pszText && lstrlenW(pDispInfo->item.pszText) > 0) { if(g_fUnicodeListView) { W_ListView_SetItemText(m_aDlgItems[c_TopicsList].m_hWnd, pDispInfo->item.iItem, 0, pDispInfo->item.pszText) ; } else { ListView_SetItemText(m_aDlgItems[c_TopicsList].m_hWnd, pDispInfo->item.iItem, 0, (char *)pDispInfo->item.pszText) ; } // Set changed flag. SetChanged() ; return TRUE ; // Accept Edit } } break ; } return 0; } /////////////////////////////////////////////////////////// // // Callback Functions. // /////////////////////////////////////////////////////////// // // Static DialogProc // INT_PTR CALLBACK CBookmarksNavPane::s_DialogProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { // Call member function dialog proc. if (msg == WM_INITDIALOG) { // The lParam is the this pointer for this dialog box. // Save it in the window userdata section. ::SetWindowLongPtr(hwnd, GWLP_USERDATA, lParam); } // Get the this pointer and call the non-static callback function. CBookmarksNavPane* p = reinterpret_cast(::GetWindowLongPtr(hwnd, GWLP_USERDATA)) ; if (p) { return p->DialogProc(hwnd, msg, wParam, lParam) ; } else { return FALSE ; } } /////////////////////////////////////////////////////////// // // ListViewProc // LRESULT WINAPI CBookmarksNavPane::s_ListViewProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { CBookmarksNavPane* pThis = reinterpret_cast(GetWindowLongPtr(hwnd, GWLP_USERDATA)); switch (msg) { case WM_KEYDOWN: if (wParam == VK_RETURN) { // A return means that we want to display the currently selected topic. pThis->OnDisplay() ; //Todo: Should this be a send message? return 0 ; } else if (wParam == VK_TAB) { pThis->OnTab(hwnd, c_TopicsList) ; } else if (wParam == VK_F2) { pThis->OnEdit() ; return 0 ; } break ; case WM_SYSKEYDOWN: if (wParam == VK_F10 && (GetKeyState(VK_SHIFT) < 0)) // SHIFT-F10 { pThis->ContextMenu(false) ; return 0 ; } break; } return W_DelegateWindowProc(s_lpfnlListViewWndProc, hwnd, msg, wParam, lParam); } /////////////////////////////////////////////////////////// // // KeywordComboEditProc - Subclassed the Edit Control in the Keyword Combo Box // The original reason for doing this was to save the selection location. // LRESULT WINAPI CBookmarksNavPane::s_CurrentTopicEditProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { CBookmarksNavPane* pThis = reinterpret_cast(GetWindowLongPtr(hwnd, GWLP_USERDATA)); switch (msg) { case WM_KEYDOWN: if (wParam == VK_TAB) { pThis->OnTab(hwnd,c_CurrentTopicEdit) ; return 0 ; } else if (wParam == VK_RETURN) { pThis->OnAddBookmark(); } break; case WM_CHAR: if (wParam == VK_TAB) { //Stops the beep! return 0 ; } } return W_DelegateWindowProc(s_lpfnlCurrentTopicEditProc, hwnd, msg, wParam, lParam); } /////////////////////////////////////////////////////////// // // Generic keyboard handling for all btns. // LRESULT WINAPI CBookmarksNavPane::s_GenericBtnProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_KEYDOWN: if (wParam == VK_RETURN) { // Do the command associated with this btn. CBookmarksNavPane* pThis = reinterpret_cast(GetWindowLongPtr(hwnd, GWLP_USERDATA)); return pThis->OnCommand(pThis->m_hWnd, ::GetDlgCtrlID(hwnd), BN_CLICKED, lParam) ; // TODO: Should this be a sendmessage? } else if (wParam == VK_TAB) { CBookmarksNavPane* pThis = reinterpret_cast(GetWindowLongPtr(hwnd, GWLP_USERDATA)); pThis->OnTab(hwnd,c_NumDlgItems) ; return 0 ; } else if (wParam == VK_LEFT || wParam == VK_RIGHT || wParam == VK_UP || wParam == VK_DOWN) { CBookmarksNavPane* pThis = reinterpret_cast(GetWindowLongPtr(hwnd, GWLP_USERDATA)); pThis->OnArrow(hwnd,c_NumDlgItems, wParam) ; return 0 ; } break; } return W_DelegateWindowProc(s_lpfnlGenericBtnProc, hwnd, msg, wParam, lParam); } /////////////////////////////////////////////////////////// // // DialogProc // INT_PTR CBookmarksNavPane::DialogProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { case WM_COMMAND: return OnCommand(hwnd, LOWORD(wParam), HIWORD(wParam), lParam) ; break ; case WM_NOTIFY: return OnNotify(hwnd, wParam, lParam) ; case WM_INITDIALOG: break; case WM_SHOWWINDOW: { BOOL bActive = (BOOL) wParam ; if (bActive) { FillCurrentTopicEdit() ; } } break ; case WM_ACTIVATE: { int active = LOWORD(wParam) ; if (active != WA_INACTIVE) { FillCurrentTopicEdit() ; } } break ; } return FALSE; }