1753 lines
53 KiB
C++
1753 lines
53 KiB
C++
|
///////////////////////////////////////////////////////////
|
||
|
//
|
||
|
//
|
||
|
// 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;
|
||
|
}
|
||
|
|
||
|
|