|
|
///////////////////////////////////////////////////////////
//
//
// 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 <windowsx.h>
#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<LPARAM>(this))) ) // Pass over the this pointer.
{ bUnicode = FALSE; if (! (m_hWnd = CreateDialogParamA( _Module.GetResourceInstance(), MAKEINTRESOURCEA(IDPAGE_TAB_BOOKMARKS), hwndParent, s_DialogProc, reinterpret_cast<LPARAM>(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<LONG_PTR>(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<LONG_PTR>(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<LONG_PTR>(s_GenericBtnProc), bUnicode); SETTHIS(m_aDlgItems[c_DeleteBtn].m_hWnd);
// Bitmap btn
W_SubClassWindow(m_aDlgItems[c_DisplayBtn].m_hWnd, reinterpret_cast<LONG_PTR>(s_GenericBtnProc), bUnicode); SETTHIS(m_aDlgItems[c_DisplayBtn].m_hWnd);
// c_DisplayBtn
W_SubClassWindow(m_aDlgItems[c_AddBookmarkBtn].m_hWnd, reinterpret_cast<LONG_PTR>(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<CBookmarksNavPane*>(::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<CBookmarksNavPane*>(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<CBookmarksNavPane*>(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<CBookmarksNavPane*>(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<CBookmarksNavPane*>(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<CBookmarksNavPane*>(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; }
|