5976 lines
155 KiB
C++
5976 lines
155 KiB
C++
//-----------------------------------------------------------------------------
|
|
// Microsoft OLE DB RowsetViewer
|
|
// Copyright (C) 1994 - 1999 By Microsoft Corporation.
|
|
//
|
|
// @doc
|
|
//
|
|
// @module CDIALOGLITE.CPP
|
|
//
|
|
//-----------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Includes
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////
|
|
#include "Headers.h"
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Globals
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////
|
|
CAppLite* g_pCAppLite = NULL;
|
|
CAppLite* GetAppLite() { return g_pCAppLite; }
|
|
void SetAppLite(CAppLite* pCAppLite) { g_pCAppLite = pCAppLite; }
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// WinMain
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
int PASCAL WinMain(
|
|
HINSTANCE hInstance,
|
|
HINSTANCE hPrevInstance,
|
|
LPSTR lpCmdLine,
|
|
int nCmdShow
|
|
)
|
|
{
|
|
//Should have a static CAppLite object at this point...
|
|
CAppLite* pCAppLite = GetAppLite();
|
|
ASSERT(pCAppLite);
|
|
|
|
//Create CWndApp
|
|
if(!pCAppLite->AppInitialize(hInstance, hPrevInstance, lpCmdLine, nCmdShow))
|
|
return -1;
|
|
|
|
//Init
|
|
if(!pCAppLite->InitInstance())
|
|
return pCAppLite->ExitInstance();
|
|
|
|
//Make sure we have a CMainWindow setup at this point...
|
|
if(!CAppLite::m_pCMainWindow || !CAppLite::m_pCMainWindow->m_hWnd)
|
|
return pCAppLite->ExitInstance();
|
|
|
|
//Run
|
|
if(!pCAppLite->Run())
|
|
return pCAppLite->ExitInstance();
|
|
|
|
//Exit
|
|
return pCAppLite->ExitInstance();
|
|
}
|
|
|
|
|
|
|
|
|
|
HWND CAppLite::m_hWndModeless = NULL; //Static
|
|
CFrameWndLite* CAppLite::m_pCMainWindow = NULL; //Static
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CAppLite::CAppLite
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
CAppLite::CAppLite(UINT nAppID)
|
|
{
|
|
m_nAppID = nAppID;
|
|
|
|
//Need to setup global CAppLite
|
|
SetAppLite(this);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CAppLite::~CAppLite
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
CAppLite::~CAppLite()
|
|
{
|
|
SetAppLite(NULL);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CAppLite::AppInitialize
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CAppLite::AppInitialize(HINSTANCE hInstance, HINSTANCE hPrevInstance, CHAR* pszCmdLine, INT nCmdShow)
|
|
{
|
|
m_hInstance = hInstance;
|
|
m_hPrevInstance = hPrevInstance;
|
|
m_pszCmdLine = pszCmdLine;
|
|
m_nCmdShow = nCmdShow;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CAppLite::InitInstance
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CAppLite::InitInstance()
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CAppLite::Run
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
int CAppLite::Run()
|
|
{
|
|
MSG msg;
|
|
|
|
//load accelerators
|
|
HACCEL hAccel = LoadAccelerators(m_hInstance, MAKEINTRESOURCE(m_nAppID));
|
|
|
|
// acquire and dispatch messages until a WM_QUIT message is received
|
|
while(GetMessage(&msg, NULL, 0, 0))
|
|
{
|
|
//Modeless dialog boxes...
|
|
if(m_hWndModeless && IsWindow(m_hWndModeless) && IsDialogMessage(m_hWndModeless, &msg))
|
|
continue;
|
|
|
|
//Main Window Translation?
|
|
if(m_pCMainWindow)
|
|
{
|
|
if(m_pCMainWindow->PreTranslateMessage(&msg))
|
|
continue;
|
|
}
|
|
|
|
//Check for App accelerators
|
|
if(hAccel && TranslateAccelerator(m_pCMainWindow->m_hWnd, hAccel, &msg))
|
|
continue;
|
|
|
|
// if the message does not need special processing, dispatch it
|
|
TranslateMessage(&msg);
|
|
DispatchMessage(&msg);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CAppLite::ExitInstance
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
int CAppLite::ExitInstance()
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CWndLite::CWndLite
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
CWndLite::CWndLite(HWND hWndParent, UINT nID)
|
|
{
|
|
m_hWnd = NULL;
|
|
m_hWndParent = NULL;
|
|
m_pwszClassName = NULL;
|
|
m_nID = 0;
|
|
m_bUnicodeMsg = IsUnicodeOS();
|
|
|
|
if(hWndParent && nID)
|
|
CreateIndirect(hWndParent, nID);
|
|
|
|
//SubClass
|
|
m_pSubClassProc = NULL;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CWndLite::~CWndLite
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
CWndLite::~CWndLite()
|
|
{
|
|
SAFE_FREE(m_pwszClassName);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CWndLite::PreCreateWindow
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CWndLite::PreCreateWindow(CREATESTRUCTW& cs)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CWndLite::Create
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CWndLite::Create(HWND hWndParent, WCHAR* pwszClassName,
|
|
WCHAR* pwszWindowName, UINT uID,
|
|
DWORD dwStyle, DWORD dwExStyle,
|
|
int x, int y, int cx, int cy)
|
|
{
|
|
ASSERT(IsDestroyed());
|
|
m_hWndParent = hWndParent;
|
|
|
|
//Setup CreateStruct
|
|
CREATESTRUCTW cs;
|
|
cs.dwExStyle = dwExStyle;
|
|
cs.lpszClass = pwszClassName;
|
|
cs.lpszName = pwszWindowName;
|
|
cs.style = dwStyle;
|
|
cs.x = x;
|
|
cs.y = y;
|
|
cs.cx = cx;
|
|
cs.cy = cy;
|
|
cs.hwndParent = hWndParent;
|
|
cs.hMenu = (HMENU)(ULONG_PTR)uID;
|
|
cs.hInstance = GetAppLite()->m_hInstance;
|
|
cs.lpCreateParams = this;
|
|
|
|
//Allow Modification of CreateParams...
|
|
if(!PreCreateWindow(cs))
|
|
return FALSE;
|
|
|
|
//Convert the Params
|
|
CHAR szClassName[MAX_NAME_LEN] = {0};
|
|
ConvertToMBCS(pwszClassName, szClassName, MAX_NAME_LEN);
|
|
CHAR szWindowName[MAX_NAME_LEN] = {0};
|
|
ConvertToMBCS(pwszWindowName, szWindowName, MAX_NAME_LEN);
|
|
|
|
//Copy the Class Name
|
|
SAFE_FREE(m_pwszClassName);
|
|
m_pwszClassName = wcsDuplicate(pwszClassName);
|
|
|
|
//Actually CreateWindowEx
|
|
m_hWnd = CreateWindowExA(cs.dwExStyle, szClassName,
|
|
szWindowName, cs.style, cs.x, cs.y, cs.cx, cs.cy,
|
|
cs.hwndParent, cs.hMenu, cs.hInstance, cs.lpCreateParams);
|
|
|
|
//Assoicate this window with this class
|
|
if(m_hWnd)
|
|
{
|
|
SetThis(m_hWnd, this);
|
|
return OnInitialUpdate();
|
|
}
|
|
|
|
GETLASTERROR(m_hWnd)
|
|
return NULL;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CWndLite::CreateIndirect
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CWndLite::CreateIndirect(HWND hWndParent, UINT nID)
|
|
{
|
|
m_nID = nID;
|
|
|
|
if(nID)
|
|
{
|
|
//Its a control on a window
|
|
m_hWnd = ::GetDlgItem(hWndParent, m_nID);
|
|
m_hWndParent = hWndParent;
|
|
}
|
|
else
|
|
{
|
|
//Its just a window
|
|
m_hWnd = hWndParent;
|
|
m_hWndParent = GetParent(m_hWnd);
|
|
}
|
|
|
|
//TODO:
|
|
//Some messages (ie: EM_GETTEXTRANGE), since their is not a W-unicode and A-ansi version),
|
|
//the message is completly based upon how you created the window. If we created the window
|
|
//incorectly, then we are limited to how the resource created it which is basically how you
|
|
//compile the source. Its also dependent upon weither you subclass the window.
|
|
//(SetWindowLongPtrA or SetWindowLongW).
|
|
#ifndef UNICODE
|
|
m_bUnicodeMsg = FALSE;
|
|
#endif
|
|
|
|
if(m_hWnd)
|
|
{
|
|
//NOTE: You only need to save the "this" pointer if your going
|
|
//to subclass the window. Otherwise two simple classes on a window control
|
|
//will end up overwriting each other. So we moved this to SubClassWindow
|
|
return OnInitialUpdate();
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CWndLite::OnInitialUpdate
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CWndLite::OnInitialUpdate()
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CWndLite::DestroyWindow
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CWndLite::DestroyWindow()
|
|
{
|
|
if(m_hWnd)
|
|
{
|
|
::DestroyWindow(m_hWnd);
|
|
m_hWnd = NULL;
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CWndLite::SubClassWindow
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CWndLite::SubClassWindow(WNDPROC pWndProc)
|
|
{
|
|
//NOTE: This method does not handle multiple levels...
|
|
ASSERT(m_pSubClassProc == NULL);
|
|
|
|
//Save the "this" pointer (in case we haven't already, for the case where
|
|
//we are subclassing a window thats already created - CreateIndirect).
|
|
SetThis(m_hWnd, this);
|
|
|
|
m_pSubClassProc = (WNDPROC)GetWindowLongPtr(m_hWnd, GWLP_WNDPROC);
|
|
SetWindowLongPtr(m_hWnd, GWLP_WNDPROC, (LONG_PTR)pWndProc);
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CWndLite::OnCreate
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CWndLite::OnCreate(CREATESTRUCT* pCREATESTRUCT)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CWndLite::OnCommandNotify
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CWndLite::OnCommandNotify(INT wNotifyCode, INT iID, HWND hWndCtrl)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CWndLite::OnCommand
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CWndLite::OnCommand(UINT iID, HWND hWndCtrl)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CWndLite::OnUpdateCommand
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CWndLite::OnUpdateCommand(HMENU hMenu, UINT nID, DWORD* pdwFlags)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CWndLite::OnNotify
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CWndLite::OnNotify(INT idCtrl, NMHDR* pNMHDR)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CWndLite::OnActivate
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CWndLite::OnActivate(UINT fActive, UINT fMinimized, HWND hWndPrevious)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CWndLite::OnClose
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CWndLite::OnClose()
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CWndLite::OnDestroy
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CWndLite::OnDestroy()
|
|
{
|
|
//Remove our Class from the hWnd lookup...
|
|
SetThis(m_hWnd, NULL);
|
|
|
|
//Remove window items...
|
|
m_hWnd = NULL;
|
|
m_hWndParent = NULL;
|
|
SAFE_FREE(m_pwszClassName);
|
|
m_pSubClassProc = NULL;
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CWndLite::OnTimer
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CWndLite::OnTimer(WPARAM nIDEvent)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CWndLite::OnDropFiles
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CWndLite::OnDropFiles(HDROP hDrop)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CWndLite::OnSysCommand
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CWndLite::OnSysCommand(WPARAM nCmdType, REFPOINTS pts)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CWndLite::OnSize
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CWndLite::OnSize(WPARAM nType, REFPOINTS pts)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CWndLite::OnSizing
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CWndLite::OnSizing(WPARAM nSize, REFPOINTS pts)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CWndLite::OnMove
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CWndLite::OnMove(REFPOINTS pts)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CWndLite::OnMouseMove
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CWndLite::OnMouseMove(WPARAM nHittest, REFPOINTS pts)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CWndLite::OnDblclk
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CWndLite::OnDblclk(WPARAM fwKeys, REFPOINTS pts)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CWndLite::OnLButtonDown
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CWndLite::OnLButtonDown(WPARAM fwKeys, REFPOINTS pts)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CWndLite::OnLButtonUp
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CWndLite::OnLButtonUp(WPARAM fwKeys, REFPOINTS pts)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CWndLite::OnRButtonDown
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CWndLite::OnRButtonDown(WPARAM fwKeys, REFPOINTS pts)
|
|
{
|
|
//NOTE: The right mouse button doesn't automatically activate the MDI window...
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CWndLite::OnRButtonUp
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CWndLite::OnRButtonUp(WPARAM fwKeys, REFPOINTS pts)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CWndLite::OnSetCursor
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CWndLite::OnSetCursor(HWND hWnd, INT nHittest, INT nMouseMsg)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CWndLite::OnContextMenu
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CWndLite::OnContextMenu(HWND hWnd, REFPOINTS pts)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CWndLite::OnChar
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CWndLite::OnChar(TCHAR chCharCode, LPARAM lKeyData)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CWndLite::OnKeyDown
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CWndLite::OnKeyDown(WPARAM nVirtKey, LPARAM lKeyData)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CWndLite::OnSysKeyDown
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CWndLite::OnSysKeyDown(WPARAM nVirtKey, LPARAM lKeyData)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CWndLite::OnVScroll
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CWndLite::OnVScroll(int nScrollCode, int nPos, HWND hWnd)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CWndLite::OnHScroll
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CWndLite::OnHScroll(int nScrollCode, int nPos, HWND hWnd)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CWndLite::OnNCMouseMove
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CWndLite::OnNCMouseMove(WPARAM nHittest, REFPOINTS pts)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CWndLite::OnNCButtonDown
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CWndLite::OnNCButtonDown(WPARAM nHittest, REFPOINTS pts)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CWndLite::OnSetFocus
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
BOOL CWndLite::OnSetFocus(HWND hWndPrevFocus)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
// CWndLite::OnMenuSelect
|
|
//
|
|
/////////////////////////////////////////////////////////////////
|
|
BOOL CWndLite::OnMenuSelect(UINT uID)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
// CWndLite::OnInitMenuPopup
|
|
//
|
|
/////////////////////////////////////////////////////////////////
|
|
BOOL CWndLite::OnInitMenuPopup(HMENU hMenu, UINT uPos, BOOL fSysMenu)
|
|
{
|
|
//Ignore the msg if it is for a system menu
|
|
if(fSysMenu)
|
|
return FALSE;
|
|
|
|
//Go through the menu items for current popup menu
|
|
//and enable/disable menu item, if required
|
|
|
|
//Also note that HandleMenuPos is a recursive algortym. This is for the
|
|
//case where I need to detmerine if a "submenu->" is enabled or diasbled.
|
|
//The only way to really tell is to know if there are any subitems that
|
|
//are needed, but some of the subitems inturn may be "submenu->".
|
|
//Therefore a item will be enabled if there is at least one subitem
|
|
//The is wanted, and disabled if there are no subitems wanted.
|
|
INT iMenuItems = GetMenuItemCount(hMenu);
|
|
DWORD dwFlags = 0;
|
|
for(LONG i=0; i<iMenuItems; i++)
|
|
{
|
|
dwFlags = 0;
|
|
if(HandleMenuPos(hMenu, i, &dwFlags))
|
|
{
|
|
EnableMenuItem(hMenu, i, MF_BYPOSITION | dwFlags);
|
|
CheckMenuItem(hMenu, i, MF_BYPOSITION | dwFlags);
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
// CWndLite::HandleMenuPos
|
|
//
|
|
/////////////////////////////////////////////////////////////////
|
|
BOOL CWndLite::HandleMenuPos(HMENU hMenu, UINT uPos, DWORD* pdwFlags)
|
|
{
|
|
ASSERT(pdwFlags);
|
|
*pdwFlags = 0;
|
|
ULONG ulMenuID = GetMenuItemID(hMenu, uPos);
|
|
|
|
//SubMenu
|
|
if(ulMenuID == ULONG_MAX)
|
|
{
|
|
BOOL bHandled = FALSE;
|
|
|
|
//Recursive Alogorytm
|
|
HMENU hSubMenu = GetSubMenu(hMenu, uPos);
|
|
INT iItems = GetMenuItemCount(hSubMenu);
|
|
for(LONG i=0; i<iItems; i++)
|
|
{
|
|
//As soon as we find one menu item that we handle, we can return
|
|
//since we now know the entire sub menu needs to be enabled for this item...
|
|
if(HandleMenuPos(hSubMenu, i, pdwFlags))
|
|
{
|
|
bHandled = TRUE;
|
|
if(*pdwFlags == MF_ENABLED)
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return bHandled;
|
|
}
|
|
|
|
//Otherwise we have a valid Menu ID...
|
|
return OnUpdateCommand(hMenu, ulMenuID, pdwFlags);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CWndLite::HandleMessage
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CWndLite::HandleMessage(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
switch(msg)
|
|
{
|
|
case WM_COMMAND:
|
|
{
|
|
UINT wNotifyCode = HIWORD(wParam); // notification code
|
|
UINT iID = LOWORD(wParam); // item, control, or accelerator identifier
|
|
HWND hWndCtrl = (HWND)lParam; // handle of control
|
|
|
|
//Filter out any Control Notification codes
|
|
// wNotifyCode - Specifies the notification code if the message is from a control. If the message is from an accelerator, this parameter is 1. If the message is from a menu, this parameter is 0.
|
|
// wID - Specifies the identifier of the menu item, control, or accelerator.
|
|
// hwndCtl - Identifies the control sending the message if the message is from a control. Otherwise, this parameter is NULL.
|
|
if(hWndCtrl && wNotifyCode)
|
|
return OnCommandNotify(wNotifyCode, iID, hWndCtrl);
|
|
|
|
return OnCommand(iID, hWndCtrl);
|
|
}
|
|
|
|
case WM_SYSCOMMAND:
|
|
return OnSysCommand(wParam, MAKEPOINTS(lParam));
|
|
|
|
case WM_ACTIVATE:
|
|
return OnActivate(LOWORD(wParam), HIWORD(wParam), (HWND)lParam);
|
|
|
|
case WM_MENUSELECT:
|
|
return OnMenuSelect(LOWORD(wParam));
|
|
|
|
case WM_INITMENUPOPUP:
|
|
return OnInitMenuPopup((HMENU)wParam, LOWORD(lParam), HIWORD(lParam));
|
|
|
|
case WM_NOTIFY:
|
|
return OnNotify((INT)wParam, (NMHDR*)lParam);
|
|
|
|
case WM_CLOSE:
|
|
return OnClose();
|
|
|
|
case WM_DESTROY:
|
|
return OnDestroy();
|
|
|
|
case WM_TIMER:
|
|
return OnTimer(wParam);
|
|
|
|
case WM_DROPFILES:
|
|
return OnDropFiles((HDROP)wParam);
|
|
|
|
case WM_SIZE:
|
|
return OnSize(wParam, MAKEPOINTS(lParam));
|
|
|
|
case WM_SIZING:
|
|
return OnSizing(wParam, MAKEPOINTS(lParam));
|
|
|
|
case WM_MOVE:
|
|
return OnMove(MAKEPOINTS(lParam));
|
|
|
|
case WM_MOUSEMOVE:
|
|
return OnMouseMove(wParam, MAKEPOINTS(lParam));
|
|
|
|
case WM_LBUTTONDBLCLK:
|
|
return OnDblclk(wParam, MAKEPOINTS(lParam));
|
|
|
|
case WM_LBUTTONDOWN:
|
|
return OnLButtonDown(wParam, MAKEPOINTS(lParam));
|
|
|
|
case WM_LBUTTONUP:
|
|
return OnLButtonUp(wParam, MAKEPOINTS(lParam));
|
|
|
|
case WM_RBUTTONDOWN:
|
|
return OnRButtonDown(wParam, MAKEPOINTS(lParam));
|
|
|
|
case WM_RBUTTONUP:
|
|
return OnRButtonUp(wParam, MAKEPOINTS(lParam));
|
|
|
|
case WM_CONTEXTMENU:
|
|
return OnContextMenu((HWND)wParam, MAKEPOINTS(lParam));
|
|
|
|
case WM_CHAR:
|
|
return OnChar((TCHAR)wParam, lParam);
|
|
|
|
case WM_KEYDOWN:
|
|
return OnKeyDown(wParam, lParam);
|
|
|
|
case WM_SYSKEYDOWN:
|
|
return OnSysKeyDown(wParam, lParam);
|
|
|
|
case WM_VSCROLL:
|
|
return OnVScroll(LOWORD(wParam), HIWORD(wParam), (HWND) lParam);
|
|
|
|
case WM_HSCROLL:
|
|
return OnHScroll(LOWORD(wParam), HIWORD(wParam), (HWND) lParam);
|
|
|
|
case WM_NCMOUSEMOVE:
|
|
return OnNCMouseMove(wParam, MAKEPOINTS(lParam));
|
|
|
|
case WM_NCLBUTTONDOWN:
|
|
return OnNCButtonDown(wParam, MAKEPOINTS(lParam));
|
|
|
|
case WM_SETFOCUS:
|
|
return OnSetFocus((HWND)wParam);
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CWndLite::UnhandledMessage
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
LRESULT CWndLite::UnhandledMessage(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
return DefWindowProc(hWnd, msg, wParam, lParam);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CWndLite::WndProc
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
LRESULT WINAPI CWndLite::WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
CWndLite* pCWndLite = (CWndLite*)GetThis(hWnd);
|
|
|
|
switch(msg)
|
|
{
|
|
case WM_CREATE:
|
|
{
|
|
//Save the Window Handle
|
|
CREATESTRUCT* pCS = (CREATESTRUCT*)lParam;
|
|
pCWndLite = (CWndLite*)pCS->lpCreateParams;
|
|
pCWndLite->m_hWnd = hWnd;
|
|
|
|
//Save the "this" pointer
|
|
SetThis(hWnd, pCWndLite);
|
|
if(pCWndLite->OnCreate(pCS))
|
|
return 0;
|
|
return -1;
|
|
}
|
|
};
|
|
|
|
//Otherwise just pass on message to original control
|
|
if(pCWndLite)
|
|
{
|
|
//Pass onto our handler
|
|
if(pCWndLite->HandleMessage(hWnd, msg, wParam, lParam))
|
|
return 0;
|
|
|
|
//Pass onto SubClass'd window, if their is one...
|
|
if(pCWndLite->m_pSubClassProc)
|
|
return CallWindowProc(pCWndLite->m_pSubClassProc, hWnd, msg, wParam, lParam);
|
|
|
|
//Otherwise pass onto our default handler
|
|
return pCWndLite->UnhandledMessage(hWnd, msg, wParam, lParam);
|
|
}
|
|
|
|
return DefWindowProc(hWnd, msg, wParam, lParam);
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CMDIChildLite::CMDIChildLite
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
CMDIChildLite::CMDIChildLite()
|
|
{
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CMDIChildLite::~CMDIChildLite
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
CMDIChildLite::~CMDIChildLite()
|
|
{
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CMDIChildLite::Create
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CMDIChildLite::Create
|
|
(
|
|
HWND hWndMDIClient,
|
|
WCHAR* pwszClassName,
|
|
WCHAR* pwszWindowName,
|
|
UINT uID,
|
|
HICON hIcon,
|
|
DWORD dwStyle,
|
|
DWORD dwExStyle,
|
|
int x,
|
|
int y,
|
|
int cx,
|
|
int cy
|
|
)
|
|
{
|
|
ASSERT(IsDestroyed());
|
|
m_hWndParent = hWndMDIClient;
|
|
WNDCLASS wc;
|
|
|
|
//Convert the Params
|
|
CHAR szClassName[MAX_NAME_LEN] = {0};
|
|
ConvertToMBCS(pwszClassName, szClassName, MAX_NAME_LEN);
|
|
CHAR szWindowName[MAX_NAME_LEN] = {0};
|
|
ConvertToMBCS(pwszWindowName, szWindowName, MAX_NAME_LEN);
|
|
|
|
// Register MDI Window classes, if we haven't done so already...
|
|
if(!GetClassInfo(GetAppLite()->m_hInstance, szClassName, &wc))
|
|
{
|
|
wc.style = 0;
|
|
wc.lpfnWndProc = MDIWndProc;
|
|
wc.cbClsExtra = 0;
|
|
wc.cbWndExtra = DLGWINDOWEXTRA;
|
|
wc.hInstance = GetAppLite()->m_hInstance;
|
|
wc.hIcon = hIcon;
|
|
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
|
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
|
|
wc.lpszMenuName = MAKEINTRESOURCE(uID);
|
|
wc.lpszClassName = szClassName;
|
|
|
|
// register MDI Child Window Class
|
|
if(!RegisterClass(&wc))
|
|
return FALSE;
|
|
}
|
|
|
|
//Setup CreateStruct
|
|
CREATESTRUCTW cs;
|
|
cs.dwExStyle = dwExStyle;
|
|
cs.lpszClass = pwszClassName;
|
|
cs.lpszName = pwszWindowName;
|
|
cs.style = dwStyle;
|
|
cs.x = x;
|
|
cs.y = y;
|
|
cs.cx = cx;
|
|
cs.cy = cy;
|
|
cs.hwndParent = m_hWndParent;
|
|
cs.hMenu = (HMENU)(ULONG_PTR)uID;
|
|
cs.hInstance = GetAppLite()->m_hInstance;
|
|
cs.lpCreateParams = this;
|
|
|
|
//Allow Modification of CreateParams...
|
|
if(!PreCreateWindow(cs))
|
|
return FALSE;
|
|
|
|
//Setup MDICREATESTRUCT for real create
|
|
MDICREATESTRUCTA mcs;
|
|
mcs.szClass = szClassName;
|
|
mcs.szTitle = szWindowName;
|
|
mcs.hOwner = cs.hInstance;
|
|
mcs.x = cs.x;
|
|
mcs.y = cs.y;
|
|
mcs.cx = cs.cx;
|
|
mcs.cy = cs.cy;
|
|
mcs.style = cs.style;
|
|
mcs.lParam = (LPARAM)this;
|
|
|
|
//Copy the Class Name
|
|
SAFE_FREE(m_pwszClassName);
|
|
m_pwszClassName = wcsDuplicate(pwszClassName);
|
|
|
|
//Create the window through the MDICLIENT window
|
|
m_hWnd = (HWND)::SendMessage(hWndMDIClient, WM_MDICREATE, 0, (LPARAM)&mcs);
|
|
|
|
//Assoicate this window with this class
|
|
if(m_hWnd)
|
|
{
|
|
SetThis(m_hWnd, this);
|
|
OnInitialUpdate();
|
|
}
|
|
|
|
return m_hWnd != NULL;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CMDIChildLite::HandleMessage
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CMDIChildLite::HandleMessage(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
switch(msg)
|
|
{
|
|
case WM_MDIACTIVATE:
|
|
return OnMDIActivate(lParam ? TRUE : FALSE, (HWND)lParam, (HWND)wParam);
|
|
}
|
|
|
|
//Otherwise delegate
|
|
return CWndLite::HandleMessage(hWnd, msg, wParam, lParam);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CMDIChildLite::OnMDIActivate
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CMDIChildLite::OnMDIActivate(BOOL bActivate, HWND hWndActivate, HWND hWndDeactivate)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CMDIChildLite::AutoPosition
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CMDIChildLite::AutoPosition(BOOL fDefaultPosition)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CMDIChildLite::UnhandledMessage
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
LRESULT CMDIChildLite::UnhandledMessage(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
return DefMDIChildProc(hWnd, msg, wParam, lParam);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CMDIChildLite::MDIWndProc
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
LRESULT WINAPI CMDIChildLite::MDIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
switch(msg)
|
|
{
|
|
case WM_CREATE:
|
|
{
|
|
//Save the Window Handle
|
|
CREATESTRUCT* pCS = (CREATESTRUCT*)lParam;
|
|
MDICREATESTRUCT* pMDICS = (MDICREATESTRUCT*)pCS->lpCreateParams;
|
|
CMDIChildLite* pCMDIChildLite = (CMDIChildLite*)pMDICS->lParam;
|
|
|
|
//Save the "this" pointer
|
|
SetThis(hWnd, pCMDIChildLite);
|
|
|
|
//NOTE: Inside CMDIChildLite::Create it has to call SendMessage
|
|
//with MDICREATE inorder to create the window. The problem is that
|
|
//the window handle is returned from the message, and user code
|
|
//within OnCreate may need the window handle to setup controls...
|
|
pCMDIChildLite->m_hWnd = hWnd;
|
|
if(pCMDIChildLite->OnCreate(pCS))
|
|
return 0;
|
|
return -1;
|
|
}
|
|
};
|
|
|
|
//Otherwise just pass on message to original control
|
|
return WndProc(hWnd, msg, wParam, lParam);
|
|
}
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CFrameWndLite::CFrameWndLite
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
CFrameWndLite::CFrameWndLite()
|
|
{
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CFrameWndLite::~CFrameWndLite
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
CFrameWndLite::~CFrameWndLite()
|
|
{
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CFrameWndLite::Create
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CFrameWndLite::Create(HWND hWndParent, WCHAR* pwszClassName,
|
|
WCHAR* pwszWindowName, UINT uID, HICON hIcon,
|
|
DWORD dwStyle, DWORD dwExStyle,
|
|
int x, int y, int cx, int cy)
|
|
{
|
|
HINSTANCE hInstance = GetAppLite()->m_hInstance;
|
|
DWORD dwResult = 0;
|
|
/*
|
|
//TODO:
|
|
//Left in for the truely UNICODE port
|
|
|
|
if(IsUnicodeOS() && 0)
|
|
{
|
|
//Setup the Structure
|
|
WNDCLASSEXW wc;
|
|
wc.cbSize = sizeof(WNDCLASSEXW);
|
|
wc.style = 0;
|
|
wc.lpfnWndProc = WndProc;
|
|
wc.cbClsExtra = 0;
|
|
wc.cbWndExtra = 0;
|
|
wc.hInstance = hInstance;
|
|
wc.hIcon = hIcon;
|
|
wc.hCursor = LoadCursorW(NULL, (LPWSTR)IDC_ARROW);
|
|
wc.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE+1);
|
|
wc.lpszMenuName = MAKEINTRESOURCEW(uID);
|
|
wc.lpszClassName = pwszClassName;
|
|
wc.hIconSm = hIcon;
|
|
|
|
//Register the window class
|
|
dwResult = RegisterClassExW(&wc);
|
|
}
|
|
else
|
|
{
|
|
*/ CHAR szClassName[MAX_NAME_LEN];
|
|
ConvertToMBCS(pwszClassName, szClassName, MAX_NAME_LEN);
|
|
|
|
//Setup the Structure
|
|
WNDCLASSEXA wc;
|
|
wc.cbSize = sizeof(WNDCLASSEXA);
|
|
wc.style = 0;
|
|
wc.lpfnWndProc = WndProc;
|
|
wc.cbClsExtra = 0;
|
|
wc.cbWndExtra = 0;
|
|
wc.hInstance = hInstance;
|
|
wc.hIcon = hIcon;
|
|
wc.hCursor = LoadCursorA(NULL, (LPSTR)IDC_ARROW);
|
|
wc.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE+1);
|
|
wc.lpszMenuName = MAKEINTRESOURCEA(uID);
|
|
wc.lpszClassName = szClassName;
|
|
wc.hIconSm = hIcon;
|
|
|
|
//Register the window class
|
|
dwResult = RegisterClassExA(&wc);
|
|
/* }
|
|
*/
|
|
//Now actually Create the Window
|
|
if(dwResult)
|
|
{
|
|
//Delegate
|
|
CWndLite::Create(hWndParent, pwszClassName, pwszWindowName, NULL,
|
|
dwStyle, dwExStyle, x, y, cx, cy);
|
|
}
|
|
|
|
return m_hWnd != NULL;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CFrameWndLite::PreTranslateMessage
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CFrameWndLite::PreTranslateMessage(MSG* pmsg)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CFrameWndLite::OnNotify
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CFrameWndLite::OnNotify(INT idCtrl, NMHDR* pNMHDR)
|
|
{
|
|
//The ToolBar and Menu always send the message to the FrameWindow, and we need
|
|
//to delegate the message to our the child windows...
|
|
switch(pNMHDR->code)
|
|
{
|
|
ON_COMMAND(TTN_NEEDTEXT, OnToolTip(idCtrl, pNMHDR));
|
|
};
|
|
|
|
//Delegate
|
|
return CWndLite::OnNotify(idCtrl, pNMHDR);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CFrameWndLite::OnToolTip
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
void CFrameWndLite::OnToolTip(INT idCtrl, NMHDR* pNMHDR)
|
|
{
|
|
// Display the ToolTip text.
|
|
LPTOOLTIPTEXTA lpToolTipText = (LPTOOLTIPTEXTA)pNMHDR;
|
|
|
|
//Load the ToolTip string from the resource...
|
|
static CHAR szBuffer[MAX_NAME_LEN];
|
|
LoadStringA(GetAppLite()->m_hInstance, (UINT)lpToolTipText->hdr.idFrom, szBuffer, MAX_NAME_LEN);
|
|
lpToolTipText->lpszText = szBuffer;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CFrameWndLite::OnClose
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CFrameWndLite::OnClose()
|
|
{
|
|
return DestroyWindow();
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CFrameWndLite::OnDestroy
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CFrameWndLite::OnDestroy()
|
|
{
|
|
PostQuitMessage(0);
|
|
|
|
//Delegate
|
|
return CWndLite::OnDestroy();
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CMDIFrameLite::CMDIFrameLite
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
CMDIFrameLite::CMDIFrameLite()
|
|
{
|
|
m_hWndMDIClient = NULL;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CMDIFrameLite::~CMDIFrameLite
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
CMDIFrameLite::~CMDIFrameLite()
|
|
{
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CMDIFrameLite::UnhandledMessage
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
LRESULT CMDIFrameLite::UnhandledMessage(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
//Need to pass unhandled messges to the MDI client...
|
|
return DefFrameProc(hWnd, m_hWndMDIClient, msg, wParam, lParam);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CMDIFrameLite::OnCreate
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CMDIFrameLite::OnCreate(CREATESTRUCT* pCREATESTRUCT)
|
|
{
|
|
//Delegate
|
|
if(CFrameWndLite::OnCreate(pCREATESTRUCT))
|
|
{
|
|
//Now Create the MDI Client...
|
|
return OnCreateClient(pCREATESTRUCT);
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CMDIFrameLite::OnDestroy
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CMDIFrameLite::OnDestroy()
|
|
{
|
|
//Remove window items...
|
|
m_hWndMDIClient = NULL;
|
|
|
|
//Delegate
|
|
return CFrameWndLite::OnDestroy();
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CMDIFrameLite::OnCreateClient
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CMDIFrameLite::OnCreateClient(CREATESTRUCT* pCREATESTRUCT)
|
|
{
|
|
DWORD dwStyle = WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | /*WS_VSCROLL | WS_HSCROLL |*/ WS_VISIBLE | CS_DBLCLKS;
|
|
DWORD dwExStyle = WS_EX_CLIENTEDGE;
|
|
|
|
//Now Setup MDI CreateStruct
|
|
CLIENTCREATESTRUCT ccs;
|
|
ccs.hWindowMenu = NULL;//GetSubMenu(GetMenu(m_hWnd), 9/*IDMENU_WINDOW*/);//TODO //TODO
|
|
ccs.idFirstChild = IDC_MDICHILD;
|
|
|
|
//Now we need to Create the MDI Client Window...
|
|
m_hWndMDIClient = CreateWindowExA(dwExStyle, "MDICLIENT", NULL, dwStyle,
|
|
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
|
|
m_hWnd, (HMENU)ID_MDICLIENT, GetAppLite()->m_hInstance, (LPSTR)&ccs);
|
|
|
|
return m_hWndMDIClient != NULL;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CMDIFrameLite::OnCommandNotify
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CMDIFrameLite::OnCommandNotify(INT wNotifyCode, INT iID, HWND hWndCtrl)
|
|
{
|
|
CWndLite* pCWndLite = GetActiveWindow();
|
|
if(pCWndLite)
|
|
if(pCWndLite->OnCommandNotify(wNotifyCode, iID, hWndCtrl))
|
|
return TRUE;
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CMDIFrameLite::OnCommand
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CMDIFrameLite::OnCommand(UINT iID, HWND hWndCtrl)
|
|
{
|
|
CWndLite* pCWndLite = GetActiveWindow();
|
|
if(pCWndLite)
|
|
if(pCWndLite->OnCommand(iID, hWndCtrl))
|
|
return TRUE;
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CMDIFrameLite::OnUpdateCommand
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CMDIFrameLite::OnUpdateCommand(HMENU hMenu, UINT nID, DWORD* pdwFlags)
|
|
{
|
|
CWndLite* pCWndLite = GetActiveWindow();
|
|
if(pCWndLite)
|
|
if(pCWndLite->OnUpdateCommand(hMenu, nID, pdwFlags))
|
|
return TRUE;
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CMDIFrameLite::OnNotify
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CMDIFrameLite::OnNotify(INT idCtrl, NMHDR* pNMHDR)
|
|
{
|
|
CWndLite* pCWndLite = GetActiveWindow();
|
|
if(pCWndLite)
|
|
if(pCWndLite->OnNotify(idCtrl, pNMHDR))
|
|
return TRUE;
|
|
|
|
//Delegate
|
|
return CFrameWndLite::OnNotify(idCtrl, pNMHDR);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CMDIFrameLite::PreTranslateMessage
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CMDIFrameLite::PreTranslateMessage(MSG* pmsg)
|
|
{
|
|
//Check for MDI accelerators
|
|
return m_hWndMDIClient && TranslateMDISysAccel(m_hWndMDIClient, pmsg);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CMDIFrameLite::GetActiveWindow
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
CMDIChildLite* CMDIFrameLite::GetActiveWindow(WCHAR* pwszClassName)
|
|
{
|
|
ASSERT(m_hWndMDIClient);
|
|
|
|
//Obtain the first Active Child Window...
|
|
HWND hWndChild = GetWindow(m_hWndMDIClient, GW_CHILD);
|
|
if(hWndChild)
|
|
{
|
|
//Return the first child of the specified type...
|
|
CMDIChildLite* pCMDIChildLite = (CMDIChildLite*)GetThis(hWndChild);
|
|
if(pCMDIChildLite)
|
|
{
|
|
if(pwszClassName)
|
|
{
|
|
if(StringCompare(pwszClassName, pCMDIChildLite->m_pwszClassName))
|
|
return pCMDIChildLite;
|
|
}
|
|
else
|
|
{
|
|
return pCMDIChildLite;
|
|
}
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CMDIFrameLite::FindWindow
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
CMDIChildLite* CMDIFrameLite::FindWindow(WCHAR* pwszClassName)
|
|
{
|
|
ASSERT(pwszClassName);
|
|
|
|
//Obtain the first Active Child Window...
|
|
HWND hWndChild = GetWindow(m_hWndMDIClient, GW_CHILD);
|
|
while(hWndChild)
|
|
{
|
|
CMDIChildLite* pCMDIChildLite = (CMDIChildLite*)GetThis(hWndChild);
|
|
if(pCMDIChildLite)
|
|
{
|
|
//Return the first child of the specified type...
|
|
if(StringCompare(pCMDIChildLite->m_pwszClassName, pwszClassName))
|
|
return pCMDIChildLite;
|
|
}
|
|
|
|
//Get the Next Window
|
|
hWndChild = GetWindow(hWndChild, GW_HWNDNEXT);
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CMDIFrameLite::OnAutoPosition
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void CMDIFrameLite::OnAutoPosition()
|
|
{
|
|
//Auto Position all children...
|
|
HWND hWndChild = GetWindow(m_hWndMDIClient, GW_CHILD);
|
|
while(hWndChild)
|
|
{
|
|
CMDIChildLite* pCMDIChildLite = (CMDIChildLite*)GetThis(hWndChild);
|
|
if(pCMDIChildLite)
|
|
pCMDIChildLite->AutoPosition();
|
|
|
|
//Get the Next Window
|
|
hWndChild = GetWindow(hWndChild, GW_HWNDNEXT);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CDialogLite::CDialogLite
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
CDialogLite::CDialogLite(UINT uIDD)
|
|
{
|
|
m_uIDD = uIDD;
|
|
m_fModal = TRUE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CDialogLite::~CDialogLite
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
CDialogLite::~CDialogLite()
|
|
{
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CDialogLite::OnInitDialog
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CDialogLite::OnInitDialog()
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CDialogLite::OnActivate
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CDialogLite::OnActivate(UINT fActive, UINT fMinimized, HWND hWndPrevious)
|
|
{
|
|
if(!m_fModal)
|
|
CAppLite::m_hWndModeless = fActive ? m_hWnd : NULL;
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CDialogLite::OnOK
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CDialogLite::OnOK()
|
|
{
|
|
EndDialog(IDOK);
|
|
return TRUE;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CDialogLite::OnCancel
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CDialogLite::OnCancel()
|
|
{
|
|
EndDialog(IDCANCEL);
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CDialogLite::DoModal
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
LRESULT CDialogLite::DoModal(HWND hWndParent)
|
|
{
|
|
//Modal Dialog Box
|
|
m_hWndParent = hWndParent;
|
|
m_fModal = TRUE;
|
|
return DisplayDialog(m_uIDD, m_hWndParent, DlgProc, (LPARAM)this);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CDialogLite::CreateDlg
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
HWND CDialogLite::CreateDlg(HWND hWndParent)
|
|
{
|
|
//Modeless (non-Modal) Dialog Box
|
|
m_hWndParent = hWndParent;
|
|
m_fModal = FALSE;
|
|
return CreateDialogParam(GetAppLite()->m_hInstance, MAKEINTRESOURCE(m_uIDD), m_hWndParent, DlgProc, (LPARAM)this);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CDialogLite::EndDialog
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
void CDialogLite::EndDialog(int nResult)
|
|
{
|
|
::EndDialog(m_hWnd, nResult);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CDialogLite::HandleMessage
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CDialogLite::HandleMessage(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
switch(msg)
|
|
{
|
|
case WM_COMMAND:
|
|
{
|
|
UINT wNotifyCode = HIWORD(wParam); // notification code
|
|
UINT iID = LOWORD(wParam); // item, control, or accelerator identifier
|
|
HWND hWndCtrl = (HWND)lParam; // handle of control
|
|
|
|
//Filter out any Control Notification codes
|
|
// wNotifyCode - Specifies the notification code if the message is from a control. If the message is from an accelerator, this parameter is 1. If the message is from a menu, this parameter is 0.
|
|
// wID - Specifies the identifier of the menu item, control, or accelerator.
|
|
// hwndCtl - Identifies the control sending the message if the message is from a control. Otherwise, this parameter is NULL.
|
|
if(hWndCtrl && wNotifyCode)
|
|
return OnCommandNotify(wNotifyCode, iID, hWndCtrl);
|
|
|
|
//We are only interested in the following
|
|
switch(iID)
|
|
{
|
|
case IDOK:
|
|
return OnOK();
|
|
|
|
case IDCANCEL:
|
|
return OnCancel();
|
|
};
|
|
break;
|
|
}
|
|
};
|
|
|
|
//Otherwise pass onto our main window handler
|
|
return CWndLite::HandleMessage(hWnd, msg, wParam, lParam);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CDialogLite::DlgProc
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
INT_PTR WINAPI CDialogLite::DlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
CDialogLite* pCDialogLite = (CDialogLite*)GetThis(hWnd);
|
|
|
|
switch (msg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
{
|
|
//Save the Window Handle
|
|
pCDialogLite = (CDialogLite*)lParam;
|
|
pCDialogLite->m_hWnd = hWnd;
|
|
|
|
//Save the "this" pointer
|
|
SetThis(hWnd, pCDialogLite);
|
|
return pCDialogLite->OnInitDialog();
|
|
}
|
|
};
|
|
|
|
if(pCDialogLite)
|
|
return pCDialogLite->HandleMessage(hWnd, msg, wParam, lParam);
|
|
|
|
return FALSE;
|
|
};
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CSplitterLite::CSplitterLite
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
CSplitterLite::CSplitterLite(HWND hWndParent, UINT nID)
|
|
: CWndLite(hWndParent, nID)
|
|
{
|
|
m_pCWndTop = NULL;
|
|
m_pCWndBottom = NULL;
|
|
m_pCWndLeft = NULL;
|
|
m_pCWndRight = NULL;
|
|
|
|
m_hCursorOld = NULL;
|
|
m_hCursorTop = NULL;
|
|
m_hCursorRight = NULL;
|
|
|
|
m_iBorderCX = 0;
|
|
m_iBorderCY = 0;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CSplitterLite::SetSplitter
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CSplitterLite::SetSplitter(CSplitterLite* pCWndTop, CSplitterLite* pCWndBottom, CSplitterLite* pCWndLeft, CSplitterLite* pCWndRight)
|
|
{
|
|
m_pCWndTop = pCWndTop;
|
|
m_pCWndBottom = pCWndBottom;
|
|
m_pCWndLeft = pCWndLeft;
|
|
m_pCWndRight = pCWndRight;
|
|
|
|
//Load the appropiate cursor
|
|
m_hCursorOld = NULL;
|
|
m_hCursorTop = LoadCursor(NULL, MAKEINTRESOURCE(IDC_SIZENS));
|
|
m_hCursorRight = LoadCursor(NULL, MAKEINTRESOURCE(IDC_SIZEWE));
|
|
|
|
m_iBorderCX = GetSystemMetrics(SM_CXFIXEDFRAME);
|
|
m_iBorderCY = GetSystemMetrics(SM_CYFIXEDFRAME);
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CSplitterLite::OnBorder
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CSplitterLite::OnBorder(REFPOINTS pts, INT iBorder)
|
|
{
|
|
RECT rect;
|
|
GetWindowRect(m_hWnd, &rect);
|
|
|
|
switch(iBorder)
|
|
{
|
|
case HTLEFT:
|
|
return pts.x <= (rect.left + m_iBorderCX);
|
|
|
|
case HTRIGHT:
|
|
return pts.x >= (rect.right - m_iBorderCX);
|
|
|
|
case HTTOP:
|
|
return pts.y <= (rect.top + m_iBorderCY);
|
|
|
|
case HTBOTTOM:
|
|
return pts.y >= (rect.bottom - m_iBorderCY);
|
|
};
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CSplitterLite::OnNCMouseMove
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CSplitterLite::OnNCMouseMove(WPARAM nHittest, REFPOINTS pts)
|
|
{
|
|
//HitTest
|
|
if(nHittest == HTBORDER)
|
|
{
|
|
//HTBOTTOM
|
|
if(m_pCWndBottom && OnBorder(pts, HTBOTTOM))
|
|
{
|
|
if(m_pCWndBottom->m_pCWndTop)
|
|
m_hCursorOld = SetCursor(m_hCursorTop);
|
|
}
|
|
//HTTOP
|
|
else if(m_pCWndTop && OnBorder(pts, HTTOP))
|
|
{
|
|
if(m_pCWndTop->m_pCWndBottom)
|
|
m_hCursorOld = SetCursor(m_hCursorTop);
|
|
}
|
|
//HTRIGHT
|
|
else if(m_pCWndRight && OnBorder(pts, HTRIGHT))
|
|
{
|
|
if(m_pCWndRight->m_pCWndLeft)
|
|
m_hCursorOld = SetCursor(m_hCursorRight);
|
|
}
|
|
//HTLEFT
|
|
else if(m_pCWndLeft && OnBorder(pts, HTLEFT))
|
|
{
|
|
if(m_pCWndLeft->m_pCWndRight)
|
|
m_hCursorOld = SetCursor(m_hCursorRight);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//Restore the Cursor
|
|
if(m_hCursorOld)
|
|
{
|
|
SetCursor(m_hCursorOld);
|
|
m_hCursorOld = NULL;
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CSplitterLite::OnNCButtonDown
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CSplitterLite::OnNCButtonDown(WPARAM nHittest, REFPOINTS ptsScreen)
|
|
{
|
|
//WM_NCLBUTTONDOWN is in Screen Coordinates, relateive to the desktop.
|
|
|
|
if(nHittest == HTBORDER)
|
|
{
|
|
POINT pt;
|
|
|
|
//Is the Mouse on the Bottom Border?
|
|
if(m_pCWndBottom && OnBorder(ptsScreen, HTBOTTOM))
|
|
{
|
|
//Create the "Bounding" Rectangle...
|
|
RECT rectLeft = GetClientCoords(m_hWndParent, m_hWnd);
|
|
RECT rectRight = GetClientCoords(m_hWndParent, m_pCWndBottom->m_hWnd);
|
|
BOOL fVertical = FALSE;
|
|
|
|
//StartTracking...
|
|
if(StartTracking(ptsScreen, rectLeft, rectRight, fVertical, &pt))
|
|
{
|
|
//MoveWindow is in Screen Coordinates.
|
|
MoveWindow(m_hWnd, rectLeft.left, rectLeft.top, rectLeft.right-rectLeft.left, pt.y-rectLeft.top, FALSE);
|
|
MoveWindow(m_pCWndBottom->m_hWnd, rectRight.left, pt.y, rectRight.right-rectRight.left, rectRight.bottom - pt.y, FALSE);
|
|
|
|
if(m_pCWndRight && m_pCWndRight->m_pCWndBottom)
|
|
{
|
|
HWND hWndRight = m_pCWndRight->m_hWnd;
|
|
rectRight = GetClientCoords(m_hWndParent, hWndRight);
|
|
MoveWindow(hWndRight, rectRight.left, rectRight.top, rectRight.right-rectRight.left, pt.y - rectRight.top, FALSE);
|
|
}
|
|
|
|
if(m_pCWndBottom->m_pCWndRight && m_pCWndBottom->m_pCWndRight->m_pCWndTop)
|
|
{
|
|
HWND hWndRight = m_pCWndBottom->m_pCWndRight->m_hWnd;
|
|
rectRight = GetClientCoords(m_hWndParent, hWndRight);
|
|
MoveWindow(hWndRight, rectRight.left, pt.y, rectRight.right-rectRight.left, rectRight.bottom - pt.y, FALSE);
|
|
}
|
|
|
|
//Now invalidate all windows
|
|
InvalidateRect(m_hWndParent, NULL, FALSE);
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
//Is the Mouse on the Top Border?
|
|
if(m_pCWndTop && OnBorder(ptsScreen, HTTOP))
|
|
{
|
|
//Create the "Bounding" Rectangle...
|
|
RECT rectLeft = GetClientCoords(m_hWndParent, m_pCWndTop->m_hWnd);
|
|
RECT rectRight = GetClientCoords(m_hWndParent, m_hWnd);
|
|
BOOL fVertical = FALSE;
|
|
|
|
//StartTracking...
|
|
if(StartTracking(ptsScreen, rectLeft, rectRight, fVertical, &pt))
|
|
{
|
|
//MoveWindow is in Screen Coordinates.
|
|
MoveWindow(m_pCWndTop->m_hWnd, rectLeft.left, rectLeft.top, rectLeft.right-rectLeft.left, pt.y-rectLeft.top, FALSE);
|
|
MoveWindow(m_hWnd, rectRight.left, pt.y, rectRight.right-rectRight.left, rectRight.bottom - pt.y, FALSE);
|
|
|
|
if(m_pCWndRight && m_pCWndRight->m_pCWndTop)
|
|
{
|
|
HWND hWndRight = m_pCWndRight->m_hWnd;
|
|
rectRight = GetClientCoords(m_hWndParent, hWndRight);
|
|
MoveWindow(hWndRight, rectRight.left, pt.y, rectRight.right-rectRight.left, rectRight.bottom - pt.y, FALSE);
|
|
}
|
|
|
|
if(m_pCWndTop->m_pCWndRight && m_pCWndTop->m_pCWndRight->m_pCWndBottom)
|
|
{
|
|
HWND hWndRight = m_pCWndTop->m_pCWndRight->m_hWnd;
|
|
rectRight = GetClientCoords(m_hWndParent, hWndRight);
|
|
MoveWindow(hWndRight, rectRight.left, rectRight.top, rectRight.right-rectRight.left, pt.y - rectRight.top, FALSE);
|
|
}
|
|
|
|
//Now invalidate all windows
|
|
InvalidateRect(m_hWndParent, NULL, FALSE);
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
//Is the Mouse on the Left Border?
|
|
if(m_pCWndLeft && OnBorder(ptsScreen, HTLEFT))
|
|
{
|
|
//Create the "Bounding" Rectangle...
|
|
RECT rectLeft = GetClientCoords(m_hWndParent, m_pCWndLeft->m_hWnd);
|
|
RECT rectRight = GetClientCoords(m_hWndParent, m_hWnd);
|
|
BOOL fVertical = TRUE;
|
|
|
|
//StartTracking...
|
|
if(StartTracking(ptsScreen, rectLeft, rectRight, fVertical, &pt))
|
|
{
|
|
//MoveWindow is in Screen Coordinates.
|
|
MoveWindow(m_pCWndLeft->m_hWnd, rectLeft.left, rectLeft.top, pt.x - rectLeft.left, rectLeft.bottom - rectLeft.top, FALSE);
|
|
MoveWindow(m_hWnd, pt.x, rectRight.top, rectRight.right-pt.x, rectRight.bottom - rectRight.top, FALSE);
|
|
|
|
if(m_pCWndLeft->m_pCWndBottom)
|
|
{
|
|
HWND hWndBottom = m_pCWndLeft->m_pCWndBottom->m_hWnd;
|
|
RECT rectBottom = GetClientCoords(m_hWndParent, hWndBottom);
|
|
MoveWindow(hWndBottom, rectBottom.left, rectBottom.top, pt.x-rectBottom.left, rectBottom.bottom-rectBottom.top, FALSE);
|
|
}
|
|
|
|
//Now invalidate all windows
|
|
InvalidateRect(m_hWndParent, NULL, FALSE);
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
//Is the Mouse on the Right Border?
|
|
if(m_pCWndRight && OnBorder(ptsScreen, HTRIGHT) && m_pCWndRight->m_pCWndLeft)
|
|
{
|
|
//Create the "Bounding" Rectangle...
|
|
RECT rectLeft = GetClientCoords(m_hWndParent, m_hWnd);
|
|
RECT rectRight = GetClientCoords(m_hWndParent, m_pCWndRight->m_hWnd);
|
|
BOOL fVertical = TRUE;
|
|
|
|
//StartTracking...
|
|
if(StartTracking(ptsScreen, rectLeft, rectRight, fVertical, &pt))
|
|
{
|
|
//MoveWindow is in Screen Coordinates.
|
|
MoveWindow(m_hWnd, rectLeft.left, rectLeft.top, pt.x - rectLeft.left, rectLeft.bottom - rectLeft.top, FALSE);
|
|
MoveWindow(m_pCWndRight->m_hWnd, pt.x, rectRight.top, rectRight.right-pt.x, rectRight.bottom - rectRight.top, FALSE);
|
|
|
|
if(m_pCWndTop)
|
|
{
|
|
HWND hWndTop = m_pCWndTop->m_hWnd;
|
|
RECT rectTop = GetClientCoords(m_hWndParent, hWndTop);
|
|
MoveWindow(hWndTop, rectTop.left, rectTop.top, pt.x-rectTop.left, rectTop.bottom-rectTop.top, FALSE);
|
|
}
|
|
|
|
if(m_pCWndBottom)
|
|
{
|
|
HWND hWndBottom = m_pCWndBottom->m_hWnd;
|
|
RECT rectBottom = GetClientCoords(m_hWndParent, hWndBottom);
|
|
MoveWindow(hWndBottom, rectBottom.left, rectBottom.top, pt.x-rectBottom.left, rectBottom.bottom-rectBottom.top, FALSE);
|
|
}
|
|
|
|
//Now invalidate all windows
|
|
InvalidateRect(m_hWndParent, NULL, FALSE);
|
|
return TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CSplitterLite::DrawSplitter
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CSplitterLite::DrawSplitter(HDC hDC, BOOL fVertical, REFRECT rectLeft, REFRECT rectRight, REFPOINTS ptsClient)
|
|
{
|
|
if(fVertical)
|
|
{
|
|
//Vertical Splitter
|
|
//PatBlt - in Client Coordinates
|
|
DWORD dwTop = min(rectLeft.top, rectRight.top);
|
|
DWORD dwHeight = max(rectLeft.bottom, rectRight.bottom) - dwTop;
|
|
PatBlt(hDC, ptsClient.x, dwTop, m_iBorderCX, dwHeight, DSTINVERT);
|
|
}
|
|
else
|
|
{
|
|
//Horizontal Splitter
|
|
//PatBlt - in Client Coordinates
|
|
DWORD dwLeft = min(rectLeft.left, rectRight.left);
|
|
DWORD dwWidth = max(rectLeft.right, rectRight.right) - dwLeft;
|
|
PatBlt(hDC, dwLeft, ptsClient.y, dwWidth, m_iBorderCY, DSTINVERT);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CSplitterLite::StartTracking
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CSplitterLite::StartTracking(REFPOINTS ptsScreen, REFRECT rectLeft, REFRECT rectRight, BOOL fVertical, POINT* pPoint)
|
|
{
|
|
ASSERT(pPoint);
|
|
BOOL bTracking = TRUE;
|
|
MSG msgModal;
|
|
|
|
//Capture mouse so Frame window gets mouse messages
|
|
HDC hDC = GetDC(m_hWndParent);
|
|
SetCapture(m_hWnd);
|
|
m_hCursorOld = SetCursor(fVertical ? m_hCursorRight : m_hCursorTop);
|
|
BOOL fWithinBounds = FALSE;
|
|
|
|
RECT rect;
|
|
GetWindowRect(m_hWnd, &rect);
|
|
POINT ptLocal = { rect.left, rect.top };
|
|
ScreenToClient(m_hWndParent, &ptLocal);
|
|
|
|
//Convert Screen Coordinates to Client Coordinates...
|
|
POINT ptClient = { ptsScreen.x, ptsScreen.y};
|
|
ScreenToClient(m_hWndParent, &ptClient);
|
|
POINTS ptsClient = { (SHORT)ptClient.x, (SHORT)ptClient.y };
|
|
|
|
//Draw splitter
|
|
DrawSplitter(hDC, fVertical, rectLeft, rectRight, ptsClient);
|
|
|
|
//While the split-bar is being dragged
|
|
while (bTracking)
|
|
{
|
|
//Get mouse message
|
|
GetMessage(&msgModal, NULL, WM_MOUSEFIRST, WM_MOUSELAST);
|
|
switch (msgModal.message)
|
|
{
|
|
case WM_MOUSEMOVE:
|
|
{
|
|
//WM_MOUSEMOVE is in Client Coordindates, relateive to the client window.
|
|
SHORT px = LOWORD(msgModal.lParam);
|
|
SHORT py = HIWORD(msgModal.lParam);
|
|
|
|
//Only redraw if different position than last time
|
|
if((fVertical && px != ptsClient.x) ||
|
|
(!fVertical && py != ptsClient.y))
|
|
{
|
|
//Draw splitter - erase previous
|
|
DrawSplitter(hDC, fVertical, rectLeft, rectRight, ptsClient);
|
|
|
|
//Get new mouse positions
|
|
ptsClient.x = (SHORT)ptLocal.x + px;
|
|
ptsClient.y = (SHORT)ptLocal.y + py;
|
|
|
|
//Draw splitter - draw new
|
|
DrawSplitter(hDC, fVertical, rectLeft, rectRight, ptsClient);
|
|
}
|
|
break;
|
|
}
|
|
|
|
// End of split-bar drag
|
|
case WM_LBUTTONUP:
|
|
case WM_LBUTTONDOWN:
|
|
case WM_LBUTTONDBLCLK:
|
|
case WM_RBUTTONUP:
|
|
case WM_RBUTTONDOWN:
|
|
case WM_RBUTTONDBLCLK:
|
|
{
|
|
//WM_LBUTTONUP is in Client Coordindates, relateive to the client window.
|
|
SHORT px = LOWORD(msgModal.lParam);
|
|
SHORT py = HIWORD(msgModal.lParam);
|
|
|
|
//Draw splitter - erase previous
|
|
DrawSplitter(hDC, fVertical, rectLeft, rectRight, ptsClient);
|
|
|
|
// Get new mouse positions
|
|
ptsClient.x = (SHORT)ptLocal.x + px;
|
|
ptsClient.y = (SHORT)ptLocal.y + py;
|
|
|
|
//We Now need to resize the Window
|
|
//Only adjust windows if Mouse is within Max/Min Coords
|
|
if(fVertical)
|
|
fWithinBounds = (ptsClient.x > rectLeft.left && ptsClient.x < rectRight.right);
|
|
else
|
|
fWithinBounds = (ptsClient.y > rectLeft.top && ptsClient.y < rectRight.bottom);
|
|
|
|
bTracking = FALSE; // Break out of tracking loop
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
ReleaseCapture();
|
|
SetCursor(m_hCursorOld);
|
|
ReleaseDC(m_hWnd, hDC);
|
|
|
|
if(fWithinBounds)
|
|
{
|
|
pPoint->x = ptsClient.x;
|
|
pPoint->y = ptsClient.y;
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CScrollBarLite::CScrollBarLite
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
CScrollBarLite::CScrollBarLite()
|
|
{
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CScrollBarLite::~CScrollBarLite
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
CScrollBarLite::~CScrollBarLite()
|
|
{
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
// CScrollBarLite::SetScroll
|
|
//
|
|
/////////////////////////////////////////////////////////////////
|
|
INT CScrollBarLite::SetScroll(INT lPos, BOOL bRedraw)
|
|
{
|
|
//This function is a "superset" of the SetScrollPos, but it takes into
|
|
//acount the caller may not know the boundary of the scrollbar, and adjusts...
|
|
|
|
//First obtain the scroll bar ranges...
|
|
INT nMin, nMax;
|
|
if(GetScrollRange(&nMin, &nMax))
|
|
{
|
|
lPos = min(lPos, nMax);
|
|
lPos = max(lPos, nMin);
|
|
|
|
//Set the new range
|
|
return SetScrollPos(lPos, bRedraw);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
// CScrollBarLite::SetScrollInfo
|
|
//
|
|
//////////////////////////////////////////////////////////////////
|
|
INT CScrollBarLite::SetScrollInfo(INT iPos, INT iRangeSize, INT iPageSize, BOOL fRedraw)
|
|
{
|
|
SCROLLINFO ScrollInfo = { sizeof(SCROLLINFO), SIF_ALL, 0, iRangeSize, iPageSize, iPos, 0};
|
|
|
|
//SetScrollInfo
|
|
return ::SetScrollInfo(m_hWnd, SB_CTL, &ScrollInfo, fRedraw);
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
// CScrollBarLite::GetScrollInfo
|
|
//
|
|
//////////////////////////////////////////////////////////////////
|
|
BOOL CScrollBarLite::GetScrollInfo(INT* piPos, INT* piRangeSize, INT* piPageSize)
|
|
{
|
|
INT iPos = 0;
|
|
INT iRangeSize = 0;
|
|
INT iPageSize = 0;
|
|
|
|
SCROLLINFO ScrollInfo = { sizeof(SCROLLINFO), SIF_ALL, 0, iRangeSize, iPageSize, iPos, 0};
|
|
|
|
//SetScrollInfo
|
|
BOOL bResult = ::GetScrollInfo(m_hWnd, SB_CTL, &ScrollInfo);
|
|
|
|
//Fill in arguments
|
|
if(piPos)
|
|
*piPos = iPos;
|
|
if(piRangeSize)
|
|
*piRangeSize = iRangeSize;
|
|
if(piPageSize)
|
|
*piPageSize = iPageSize;
|
|
|
|
return bResult;
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CEditBoxLite::CEditBoxLite
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
CEditBoxLite::CEditBoxLite(HWND hWndParent, UINT nID)
|
|
: CSplitterLite(hWndParent, nID)
|
|
{
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CEditBoxLite::~CEditBoxLite
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
CEditBoxLite::~CEditBoxLite()
|
|
{
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CEditBoxLite::OnCreate
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CEditBoxLite::OnCreate(CREATESTRUCT* pCREATESTRUCT)
|
|
{
|
|
//SubClass the window
|
|
SubClassWindow(WndProc);
|
|
|
|
//Delegate
|
|
return CSplitterLite::OnCreate(pCREATESTRUCT);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CEditBoxLite::GetTextRange
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
INDEX CEditBoxLite::GetTextRange(CHARRANGE& cr, WCHAR* pwszBuffer)
|
|
{
|
|
//With EM_GETTEXTRANGE (Since their is not a W-unicode and A-ansi version), the message
|
|
//is completly based upon how you created the window. Since we currently only
|
|
//call this from CreateIndirect (ANSI) we just assume this...
|
|
if(m_bUnicodeMsg)
|
|
{
|
|
TEXTRANGEW tr;
|
|
tr.chrg = cr;
|
|
tr.lpstrText = pwszBuffer;
|
|
|
|
return (INDEX)::SendMessage(m_hWnd, EM_GETTEXTRANGE, 0, (LPARAM)&tr);
|
|
}
|
|
else
|
|
{
|
|
CHAR szBuffer[MAX_QUERY_LEN] = {0};
|
|
|
|
TEXTRANGEA tr;
|
|
tr.chrg = cr;
|
|
tr.lpstrText = szBuffer;
|
|
|
|
INDEX lReturn = (INDEX)::SendMessage(m_hWnd, EM_GETTEXTRANGE, 0, (LPARAM)&tr);
|
|
ConvertToWCHAR(szBuffer, pwszBuffer, cr.cpMax - cr.cpMin);
|
|
return lReturn;
|
|
}
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CEditBoxLite::GetTextRange
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
INDEX CEditBoxLite::GetTextRange(CHARRANGE& cr, CHAR* pszBuffer)
|
|
{
|
|
//With EM_GETTEXTRANGE (Since their is not a W-unicode and A-ansi version), the message
|
|
//is completly based upon how you created the window. Since we currently only
|
|
//call this from CreateIndirect (ANSI) we just assume this...
|
|
if(m_bUnicodeMsg)
|
|
{
|
|
WCHAR wszBuffer[MAX_QUERY_LEN] = {0};
|
|
|
|
TEXTRANGEW tr;
|
|
tr.chrg = cr;
|
|
tr.lpstrText = wszBuffer;
|
|
|
|
INDEX lReturn = (INDEX)::SendMessage(m_hWnd, EM_GETTEXTRANGE, 0, (LPARAM)&tr);
|
|
ConvertToMBCS(wszBuffer, pszBuffer, cr.cpMax - cr.cpMin);
|
|
return lReturn;
|
|
}
|
|
else
|
|
{
|
|
TEXTRANGEA tr;
|
|
tr.chrg = cr;
|
|
tr.lpstrText = pszBuffer;
|
|
|
|
return (INDEX)::SendMessage(m_hWnd, EM_GETTEXTRANGE, 0, (LPARAM)&tr);
|
|
}
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CEditBoxLite::GetLine
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
INDEX CEditBoxLite::GetLine(INDEX iLine, CHAR* pszBuffer, ULONG ulMaxSize)
|
|
{
|
|
ASSERT(pszBuffer && ulMaxSize);
|
|
|
|
//Get the Text for this Line
|
|
//EM_GETLINE assumes the first byte of the buffer
|
|
//indicates the total size of the buffer
|
|
((WORD*)pszBuffer)[0] = (WORD)(ulMaxSize-1);
|
|
INDEX iChars = (INDEX)SendMessage(m_hWnd, EM_GETLINE, iLine, (LPARAM)pszBuffer);
|
|
|
|
//Supposedly EM_GETLINE doesn't contain a NULL Terminator?!
|
|
pszBuffer[min((ULONG)iChars, ulMaxSize)] = EOL;
|
|
return iChars;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CEditBoxLite::Save
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CEditBoxLite::Save(LPCWSTR pwszFileName)
|
|
{
|
|
CFileLite cFile;
|
|
CHAR szBuffer[MAX_QUERY_LEN];
|
|
|
|
//Open the file, (prompt if error)
|
|
if(FAILED(cFile.Open(pwszFileName, GENERIC_WRITE, 0, CREATE_ALWAYS, TRUE)))
|
|
return FALSE;
|
|
|
|
//Loop over all lines in the RichEdit control and write to the file...
|
|
//Copy the contents of this ListBox to the destination...
|
|
INDEX iCount = GetLineCount();
|
|
for(INDEX i=0; i<iCount; i++)
|
|
{
|
|
//Get this line from the Control
|
|
if(!GetLine(i, szBuffer, MAX_NAME_LEN))
|
|
break;
|
|
|
|
//Blast it to the file...
|
|
cFile.Write(szBuffer);
|
|
cFile.Write(wWndEOL);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CEditBoxLite::ReplaceSelAll
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
void CEditBoxLite::ReplaceAll(LPCWSTR pwszString, bool bReplaceAll, bool bHighlight)
|
|
{
|
|
if(pwszString)
|
|
{
|
|
INDEX iStartPos = 0;
|
|
INDEX iStartPos2 = 0;
|
|
INDEX iEndPos = 0;
|
|
INDEX iEndPos2 = 0;
|
|
|
|
if(bReplaceAll)
|
|
{
|
|
//Replace the entire text?
|
|
SetSel(0, -1);
|
|
}
|
|
else
|
|
{
|
|
//Obtain the Selected Text Start and End Positions
|
|
GetSel(&iStartPos, &iEndPos);
|
|
}
|
|
|
|
//Replace the Selection
|
|
ReplaceSel(pwszString, TRUE/*fCanUndo*/);
|
|
|
|
//Make sure the replacement is visible...
|
|
ScrollCaret();
|
|
|
|
if(bHighlight)
|
|
{
|
|
if(bReplaceAll)
|
|
{
|
|
//Highlight all the text...
|
|
SetSel(0, -1);
|
|
}
|
|
else
|
|
{
|
|
//Highlight the text we used...
|
|
GetSel(&iStartPos2, &iEndPos2);
|
|
SetSel(iStartPos, iEndPos2);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CXmlDOM::CXmlDOM
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
CXmlDOM::CXmlDOM()
|
|
{
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CXmlDOM::~CXmlDOM
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
CXmlDOM::~CXmlDOM()
|
|
{
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CXmlDOM::PrintNode
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
HRESULT CXmlDOM::PrintNode(IXMLDOMNode* spNode, CConsole& rConsole, ULONG ullevel)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
CComBSTR bstrName;
|
|
CComVariant varValue;
|
|
|
|
CComPtr<IXMLDOMNamedNodeMap> spAttrs;
|
|
CComPtr<IXMLDOMNode> spChild;
|
|
|
|
//Write out this node
|
|
if(spNode)
|
|
{
|
|
//Output: Indentation Level
|
|
for(ULONG i=0; i<ullevel; i++)
|
|
rConsole << L" ";
|
|
|
|
//Node Name
|
|
TESTC(hr = spNode->get_nodeName(&bstrName));
|
|
|
|
//Node type
|
|
DOMNodeType nodeType;
|
|
TESTC(hr = spNode->get_nodeType(&nodeType));
|
|
|
|
//Node Value
|
|
TESTC(hr = spNode->get_nodeValue(&varValue));
|
|
varValue.ChangeType(VT_BSTR);
|
|
|
|
switch(nodeType)
|
|
{
|
|
case NODE_PROCESSING_INSTRUCTION:
|
|
rConsole << RGB_BLUE << L"<?" << RGB_NONE;
|
|
rConsole << RGB_BLUE << bstrName << RGB_NONE;
|
|
|
|
//Output: Attributes
|
|
PrintAttributes(spNode, rConsole);
|
|
|
|
//Output: >
|
|
rConsole << RGB_BLUE << L" ?>" << RGB_NONE;
|
|
rConsole.WriteLine();
|
|
break;
|
|
|
|
case NODE_DOCUMENT_TYPE:
|
|
{
|
|
//<!DOCTYPE root (View Source for full doctype...)>
|
|
rConsole << RGB_BLUE << L"<!DOCTYPE " << bstrName;
|
|
rConsole << CA_ITALIC << L" (View Source for full doctype...)" << CA_NORMAL;
|
|
rConsole.WriteLine();
|
|
break;
|
|
}
|
|
|
|
case NODE_TEXT:
|
|
//This is the text of a node, not an element (ie: doesn't need tags)
|
|
rConsole << CA_BOLD << V_BSTR(&varValue) << CA_NORMAL;
|
|
rConsole.WriteLine();
|
|
break;
|
|
|
|
default:
|
|
ASSERT(!"Unhandled Node Type?");
|
|
//FALL THROUGH TO DISPLAY UNKNOWN ELEMENT
|
|
|
|
case NODE_ELEMENT:
|
|
case NODE_DOCUMENT:
|
|
//Output: <ElementName
|
|
rConsole << RGB_BLUE << L"<" << RGB_NONE;
|
|
rConsole << RGB_DARK_RED << bstrName << RGB_NONE;
|
|
|
|
//Output: Attributes
|
|
PrintAttributes(spNode, rConsole);
|
|
|
|
//Output: Value
|
|
rConsole << CA_BOLD << V_BSTR(&varValue) << CA_NORMAL;
|
|
|
|
//Output: >
|
|
rConsole << RGB_BLUE << L">" << RGB_NONE;
|
|
rConsole.WriteLine();
|
|
break;
|
|
|
|
}
|
|
|
|
//Now recurse into any children...
|
|
TESTC(hr = spNode->get_firstChild(&spChild));
|
|
while(spChild)
|
|
{
|
|
CComPtr<IXMLDOMNode> spNext;
|
|
|
|
//Recurse for all siblings...
|
|
TESTC(hr = PrintNode(spChild, rConsole, ullevel+1));
|
|
TESTC(hr = spChild->get_nextSibling(&spNext));
|
|
|
|
spChild.Attach(spNext);
|
|
spNext.Detach();
|
|
}
|
|
}
|
|
|
|
CLEANUP:
|
|
return hr;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CXmlDOM::PrintAttributes
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
HRESULT CXmlDOM::PrintAttributes(IXMLDOMNode* spNode, CConsole& rConsole)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
CComBSTR bstrName;
|
|
CComVariant varValue;
|
|
|
|
CComPtr<IXMLDOMNamedNodeMap> spAttrs;
|
|
CComPtr<IXMLDOMNode> spChild;
|
|
|
|
//Write out the Attributes
|
|
if(spNode)
|
|
{
|
|
//Write out all attributes
|
|
TESTC(hr = spNode->get_attributes(&spAttrs));
|
|
if(spAttrs)
|
|
{
|
|
TESTC(hr = spAttrs->nextNode(&spChild));
|
|
while(spChild)
|
|
{
|
|
//Attribute name
|
|
TESTC(hr = spChild->get_nodeName(&bstrName));
|
|
|
|
//Attribute Value
|
|
TESTC(hr = spChild->get_nodeValue(&varValue));
|
|
varValue.ChangeType(VT_BSTR);
|
|
|
|
//Node type
|
|
DOMNodeType nodeType;
|
|
TESTC(hr = spNode->get_nodeType(&nodeType));
|
|
|
|
switch(nodeType)
|
|
{
|
|
case NODE_PROCESSING_INSTRUCTION:
|
|
//Output: AttributeName="
|
|
rConsole << RGB_BLUE;
|
|
rConsole << L" " << bstrName;
|
|
rConsole << L"=\"";
|
|
|
|
//Output: AttributeValue
|
|
rConsole << V_BSTR(&varValue);
|
|
|
|
//Output: "
|
|
rConsole << L"\"" << RGB_NONE;
|
|
break;
|
|
|
|
|
|
default:
|
|
ASSERT(!"Unhandled Node Type?");
|
|
//FALL THROUGH TO DISPLAY UNKNOWN ELEMENT
|
|
|
|
case NODE_ELEMENT:
|
|
//Output: AttributeName="
|
|
rConsole << RGB_DARK_RED;
|
|
rConsole << L" " << bstrName;
|
|
rConsole << RGB_BLUE << L"=\"";
|
|
|
|
//Output: AttributeValue
|
|
rConsole << RGB_NONE << CA_BOLD << V_BSTR(&varValue);
|
|
|
|
//Output: "
|
|
rConsole << RGB_BLUE << CA_NORMAL << L"\"" << RGB_NONE;
|
|
break;
|
|
};
|
|
|
|
bstrName.Empty();
|
|
varValue.Clear();
|
|
|
|
//Next Attribute
|
|
spChild.Release();
|
|
TESTC(hr = spAttrs->nextNode(&spChild));
|
|
}
|
|
}
|
|
}
|
|
|
|
CLEANUP:
|
|
return hr;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CRichEditLite::CRichEditLite
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
CRichEditLite::CRichEditLite(HWND hWndParent, UINT nID)
|
|
: CEditBoxLite(hWndParent, nID)
|
|
{
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CRichEditLite::~CRichEditLite
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
CRichEditLite::~CRichEditLite()
|
|
{
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CRichEditLite::OnCreate
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CRichEditLite::OnCreate(CREATESTRUCT* pCREATESTRUCT)
|
|
{
|
|
//URL detection
|
|
SendMessage(m_hWnd, EM_AUTOURLDETECT, TRUE, 0);
|
|
SendMessage(m_hWnd, EM_SETEVENTMASK, 0, ENM_LINK);
|
|
|
|
//Delegate
|
|
return CEditBoxLite::OnCreate(pCREATESTRUCT);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CRichEditLite::SetWordWrap
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CRichEditLite::SetWordWrap(BOOL fWordWrap)
|
|
{
|
|
//WordWrap
|
|
// 0 - Wrap to window
|
|
// 1 - Do not wrap lines
|
|
return (BOOL)SendMessage(m_hWnd, EM_SETTARGETDEVICE, (WPARAM)NULL, fWordWrap ? 0 : 1);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CRichEditLite::SetDefaultFont
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
LRESULT CRichEditLite::SetDefaultFont()
|
|
{
|
|
//Default Font
|
|
//If you wise not to replace the font with this default, then just
|
|
//set cbSize = 0 before calling ::Create.
|
|
CHARFORMATW charFormat;
|
|
memset(&charFormat, 0, sizeof(CHARFORMATW));
|
|
charFormat.cbSize = sizeof(CHARFORMATW);
|
|
charFormat.dwMask = CFM_SIZE | CFM_COLOR | CFM_FACE | CFM_OFFSET | CFM_CHARSET | CFM_LINK | CFM_PROTECTED | CFM_STRIKEOUT | CFM_UNDERLINE | CFM_ITALIC | CFM_BOLD;
|
|
charFormat.dwEffects = CFE_AUTOCOLOR;
|
|
charFormat.yHeight = 0x60;
|
|
StringCopy(charFormat.szFaceName, L"MS Sans Serif", LF_FACESIZE);
|
|
|
|
//By default the font for RichEdit controls is HUGE! By default we will replace
|
|
//the font with the default for Edit Controls which is Sans-Serif size 8...
|
|
if(charFormat.cbSize)
|
|
return SetCharFormat(SCF_ALL, charFormat);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CRichEditLite::OnNotify
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CRichEditLite::OnNotify(INT idCtrl, NMHDR* pNMHDR)
|
|
{
|
|
switch(pNMHDR->code)
|
|
{
|
|
ON_COMMAND(EN_LINK, OnLink(idCtrl, (ENLINK*)pNMHDR));
|
|
};
|
|
|
|
//Delegate
|
|
return CEditBoxLite::OnNotify(idCtrl, pNMHDR);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CRichEditLite::OnLink
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CRichEditLite::OnLink(INT idCtrl, ENLINK* pEnLink)
|
|
{
|
|
//Default Implementation of OnLink, of actually executing the link...
|
|
if(pEnLink)
|
|
{
|
|
switch(pEnLink->msg)
|
|
{
|
|
case WM_LBUTTONDOWN:
|
|
{
|
|
//Obtain the link text.
|
|
if(pEnLink->chrg.cpMax - pEnLink->chrg.cpMin <= MAX_QUERY_LEN)
|
|
{
|
|
CWaitCursor waitCursor;
|
|
if(IsUnicodeOS())
|
|
{
|
|
WCHAR wszLink[MAX_QUERY_LEN] = {0};
|
|
GetTextRange(pEnLink->chrg, wszLink);
|
|
|
|
//ShellExecute returns a value greater than 32 is successful (nice design!)
|
|
//NOTE: ShellExecute returns a HINSTANCE, (for backard compatibility), but really this is a LONG
|
|
return (LONG_PTR)ShellExecuteW(m_hWnd, L"open", wszLink, NULL, NULL, SW_SHOWNORMAL) > 32;
|
|
}
|
|
else
|
|
{
|
|
CHAR szLink[MAX_QUERY_LEN] = {0};
|
|
GetTextRange(pEnLink->chrg, szLink);
|
|
|
|
//ShellExecute returns a value greater than 32 is successful (nice design!)
|
|
//NOTE: ShellExecute returns a HINSTANCE, (for backard compatibility), but really this is a LONG
|
|
return (LONG_PTR)ShellExecuteA(m_hWnd, "open", szLink, NULL, NULL, SW_SHOWNORMAL) > 32;
|
|
}
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CRichEditLite::ReplaceSel
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
void CRichEditLite::ReplaceSel(LPCWSTR pwszString, bool bCanUndo, DWORD dwMask, DWORD dwColor)
|
|
{
|
|
//Change to bold and/or color
|
|
if(dwMask)
|
|
SetEffects(dwMask, dwMask & CFM_BOLD ? CFE_BOLD : 0, dwColor);
|
|
|
|
//Delegate
|
|
ReplaceSel(pwszString, bCanUndo);
|
|
|
|
//Change back
|
|
if(dwMask)
|
|
SetEffects(dwMask, CFE_AUTOCOLOR, 0);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CRichEditLite::Append
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
void CRichEditLite::Append(LPCWSTR pwszString, bool bCanUndo, DWORD dwMask, DWORD dwColor)
|
|
{
|
|
//Move the position to the end
|
|
SetSel(LONG_MAX, LONG_MAX);
|
|
|
|
//Delegate
|
|
ReplaceSel(pwszString, bCanUndo, dwMask, dwColor);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CRichEditLite::GetSelectedText
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
WCHAR* CRichEditLite::GetSelectedText(BOOL fEntireLine)
|
|
{
|
|
INDEX cpMin = 0;
|
|
INDEX cpMax = 0;
|
|
WCHAR* pwsz = NULL;
|
|
HRESULT hr = S_OK;
|
|
|
|
//Obtain the EditBox text (rules below).
|
|
// 1. First try to obtain whatever text is highlighted (even multiline highlight)
|
|
// 2. Or if nothing is highlighted take the entire line of the cursor
|
|
|
|
//Obtain the Selected Text Start and End Positions
|
|
GetSel(&cpMin, &cpMax);
|
|
|
|
//If there is no selected Text
|
|
//Just get the entire line, as if it were highlighted...
|
|
if(cpMin == cpMax)
|
|
{
|
|
//Obtain the first character of the selected line...
|
|
INDEX iCharIndex = LineIndex(-1);
|
|
INDEX iLineLength = LineLength(cpMin);
|
|
|
|
if(fEntireLine)
|
|
{
|
|
cpMin = (LONG)iCharIndex;
|
|
cpMax = (LONG)(iCharIndex + iLineLength);
|
|
}
|
|
|
|
//Obtain the current word, if nothing is selected...
|
|
if(cpMin == cpMax)
|
|
{
|
|
//TODO
|
|
/* //Find the begining of the whole word that the cursor is over...
|
|
while(cpMin > iCharIndex)
|
|
{
|
|
if(!iswalnum(pwsz[cpMin - iCharIndex - 1]))
|
|
break;
|
|
cpMin--;
|
|
}
|
|
|
|
//Find the ending of the whole word that the cursor is over...
|
|
while(cpMax < (iCharIndex + iLineLength))
|
|
{
|
|
if(!iswalnum(pwsz[cpMax - iCharIndex]))
|
|
break;
|
|
cpMax++;
|
|
}
|
|
*/ }
|
|
|
|
//Highlight the text we used...
|
|
SetSel(cpMin, cpMax);
|
|
}
|
|
|
|
//Now that we have a selection...
|
|
ASSERT(cpMax>=cpMin && cpMax>=0 && cpMin>=0);
|
|
|
|
//Simple, just obtain the selected text...
|
|
INDEX iMaxChars = (cpMax-cpMin+1)+1;
|
|
|
|
//Allocate a buffer large enough to hold all the text...
|
|
//NOTE: We pass in the length to wSendMessage so it knows the conversion length...
|
|
SAFE_ALLOC(pwsz, WCHAR, iMaxChars);
|
|
wSendMessage(m_hWnd, EM_GETSELTEXT, iMaxChars, pwsz);
|
|
|
|
CLEANUP:
|
|
return pwsz;
|
|
}
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CRichEditLite::SetEffects
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CRichEditLite::SetEffects(DWORD dwMask, DWORD dwEffects, COLORREF crTextColor)
|
|
{
|
|
CHARFORMATW charFormat;
|
|
charFormat.cbSize = sizeof(CHARFORMATW);
|
|
charFormat.dwMask = dwMask;
|
|
charFormat.dwEffects = dwEffects;
|
|
charFormat.crTextColor = crTextColor;
|
|
return SetCharFormat(SCF_SELECTION, charFormat);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CRichEditLite::SetCharFormat
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CRichEditLite::SetCharFormat(DWORD dwMask, CHARFORMATW& charFormatW)
|
|
{
|
|
//Unfortunatly the RichEdit20W requires a CHARFORMATW structure (size) to be passed in
|
|
//and will ignore the CHARFORMATA size, and the same is true for RichEdit20A with CHARFORMATA.
|
|
//This is a unique structure in that this is not a pointer to a string szFaceName, but the
|
|
//string buffer is a part of the structure, making cbSize different. Even though we don't
|
|
//have the maks indicating the face name is valid, it still does validation and will ignore
|
|
//any mismatched size with the use of the control...
|
|
|
|
if(IsUnicodeOS())
|
|
{
|
|
return (BOOL)SendMessageW(m_hWnd, EM_SETCHARFORMAT, dwMask, (LPARAM)&charFormatW);
|
|
}
|
|
else
|
|
{
|
|
//Convert the CHARFORMATW to CHARFORMATA
|
|
CHARFORMATA charFormatA;
|
|
memcpy(&charFormatA, &charFormatW, sizeof(CHARFORMATA));
|
|
charFormatA.cbSize = sizeof(CHARFORMATA);
|
|
|
|
//Convert the Unicode inline string to MBCS
|
|
ConvertToMBCS(charFormatW.szFaceName, charFormatA.szFaceName, LF_FACESIZE);
|
|
return (BOOL)SendMessageA(m_hWnd, EM_SETCHARFORMAT, dwMask, (LPARAM)&charFormatA);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CRichEditLite::FindText
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
INDEX CRichEditLite::FindText(DWORD dwFindFlags, FINDTEXTEXW* pFindTextW)
|
|
{
|
|
INDEX lPos = -1;
|
|
|
|
if(IsUnicodeOS())
|
|
{
|
|
//EM_FINDTEXT
|
|
lPos = SendMessageW(m_hWnd, EM_FINDTEXTEXW, dwFindFlags, (LPARAM)pFindTextW);
|
|
}
|
|
else
|
|
{
|
|
CHAR szBuffer[MAX_NAME_LEN];
|
|
ConvertToMBCS(pFindTextW->lpstrText, szBuffer, MAX_NAME_LEN);
|
|
|
|
//Input Args
|
|
FINDTEXTEXA FindTextA;
|
|
FindTextA.chrg = pFindTextW->chrg;
|
|
FindTextA.lpstrText = szBuffer;
|
|
|
|
//EM_FINDTEXT
|
|
lPos = SendMessageA(m_hWnd, EM_FINDTEXTEX, dwFindFlags, (LPARAM)&FindTextA);
|
|
|
|
//Output Params
|
|
pFindTextW->chrgText = FindTextA.chrgText;
|
|
}
|
|
|
|
return lPos;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CRichEditLite::FindNext
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
BOOL CRichEditLite::FindNext(DWORD dwFindFlags, WCHAR* pwszText)
|
|
{
|
|
//Obtain the Current Position of the 'caret'
|
|
CHARRANGE chrg;
|
|
GetSel(&chrg);
|
|
BOOL fForward = (dwFindFlags & FR_DOWN);
|
|
|
|
//This now is the "next" or "previous" positions to search from...
|
|
//NOTE: We have to use "Min" on backward searching otherwise it will continue to find
|
|
//the selected word over and over...
|
|
chrg.cpMin = fForward ? chrg.cpMax : chrg.cpMin;
|
|
chrg.cpMax = fForward ? LONG_MAX : 0;
|
|
|
|
FINDTEXTEXW findTextEx;
|
|
findTextEx.chrg = chrg;
|
|
findTextEx.lpstrText = pwszText;
|
|
|
|
//First search from the point specified to the bottom (if forward)
|
|
INDEX iPos = FindText(dwFindFlags, &findTextEx);
|
|
if(iPos == -1)
|
|
{
|
|
//If not found, then switch to start from the begining (if forward) to the org starting point.
|
|
findTextEx.chrg.cpMin = fForward ? 0 : LONG_MAX;
|
|
findTextEx.chrg.cpMax = chrg.cpMax;
|
|
|
|
//Search
|
|
iPos = FindText(dwFindFlags, &findTextEx);
|
|
}
|
|
|
|
if(iPos != -1)
|
|
{
|
|
//Found a match, Select it...
|
|
SetSel(findTextEx.chrgText.cpMin, findTextEx.chrgText.cpMax);
|
|
return TRUE;
|
|
}
|
|
|
|
//Otherwise, not found
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CListBoxLite::CListBoxLite
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
CListBoxLite::CListBoxLite(HWND hWndParent, UINT nID)
|
|
: CWndLite(hWndParent, nID)
|
|
{
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CListBoxLite::~CListBoxLite
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
CListBoxLite::~CListBoxLite()
|
|
{
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CListBoxLite::OnCommandNotify
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CListBoxLite::OnCommandNotify(INT wNotifyCode, INT iID, HWND hWndCtrl)
|
|
{
|
|
switch(wNotifyCode)
|
|
{
|
|
case LBN_DBLCLK:
|
|
{
|
|
if(OnDblClk(iID, hWndCtrl))
|
|
return TRUE;
|
|
break;
|
|
}
|
|
};
|
|
|
|
//Otherwise Delegate
|
|
return CWndLite::OnCommandNotify(wNotifyCode, iID, hWndCtrl);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CListBoxLite::OnDblClk
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CListBoxLite::OnDblClk(INT iID, HWND hWndCtrl)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CListViewLite::CListViewLite
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
CListViewLite::CListViewLite(HWND hWndParent, UINT nID)
|
|
: CSplitterLite(hWndParent, nID)
|
|
{
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CListViewLite::~CListViewLite
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
CListViewLite::~CListViewLite()
|
|
{
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CListViewLite::OnCreate
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CListViewLite::OnCreate(CREATESTRUCT* pCREATESTRUCT)
|
|
{
|
|
//SubClass the window
|
|
SubClassWindow(WndProc);
|
|
|
|
//Delegate
|
|
return CSplitterLite::OnCreate(pCREATESTRUCT);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CListViewLite::OnNotify
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CListViewLite::OnNotify(INT idCtrl, NMHDR* pNMHDR)
|
|
{
|
|
switch(pNMHDR->code)
|
|
{
|
|
ON_COMMAND(LVN_COLUMNCLICK, OnColumnClick(idCtrl, (NMLISTVIEW*)pNMHDR));
|
|
ON_COMMAND(LVN_ITEMACTIVATE, OnItemActivate(idCtrl, (NMLISTVIEW*)pNMHDR));
|
|
ON_COMMAND(LVN_ITEMCHANGED, OnItemChanged(idCtrl, (NMLISTVIEW*)pNMHDR));
|
|
};
|
|
|
|
//Delegate
|
|
return CSplitterLite::OnNotify(idCtrl, pNMHDR);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CListViewLite::OnColumnClick
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CListViewLite::OnColumnClick(INT idCtrl, NMLISTVIEW* pNMListView)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CListViewLite::OnItemActivate
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CListViewLite::OnItemActivate(INT idCtrl, NMLISTVIEW* pNMListView)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CListViewLite::OnItemChanged
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CListViewLite::OnItemChanged(INT idCtrl, NMLISTVIEW* pNMListView)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CListViewLite::InsertItem
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
INDEX CListViewLite::InsertItem(INDEX iItem, INDEX iSubItem, WCHAR* wszName, LPARAM lParam, INT iImage, UINT iState, UINT iStateMask)
|
|
{
|
|
return LV_InsertItem(m_hWnd, iItem, iSubItem, wszName, lParam, iImage, iState, iStateMask);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CListViewLite::SetItemText
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CListViewLite::SetItemText(INDEX iItem, INDEX iSubItem, WCHAR* pwszName)
|
|
{
|
|
return LV_SetItemText(m_hWnd, iItem, iSubItem, pwszName);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CListViewLite::SetItemState
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CListViewLite::SetItemState(INDEX iItem, INDEX iSubItem, UINT iState, UINT iStateMask)
|
|
{
|
|
return LV_SetItemState(m_hWnd, iItem, iSubItem, iState, iStateMask);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CListViewLite::GetItemImage
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
INT CListViewLite::GetItemImage(INDEX iItem, INDEX iSubItem)
|
|
{
|
|
return LV_GetItemImage(m_hWnd, iItem, iSubItem);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CListViewLite::SetItemImage
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CListViewLite::SetItemImage(INDEX iItem, INDEX iSubItem, INT iImage)
|
|
{
|
|
return LV_SetItemImage(m_hWnd, iItem, iSubItem, iImage);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CListViewLite::SetItemParam
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CListViewLite::SetItemParam(INDEX iItem, INDEX iSubItem, LPARAM lParam)
|
|
{
|
|
return LV_SetItemParam(m_hWnd, iItem, iSubItem, lParam);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CListViewLite::SetColumn
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CListViewLite::SetColumn(INDEX iColumn, WCHAR* wszName, INT iImage)
|
|
{
|
|
ULONG dwMask = LVCF_TEXT | LVCF_FMT | LVCF_SUBITEM;
|
|
INT dwFmt = LVCFMT_LEFT;
|
|
if(iImage != IMAGE_NONE)
|
|
{
|
|
dwMask |= LVCF_IMAGE;
|
|
dwFmt |= LVCFMT_IMAGE;
|
|
}
|
|
|
|
//LVM_SETCOLUMN
|
|
if(IsUnicodeOS())
|
|
{
|
|
//Setup LVM_SETCOLUMN
|
|
LV_COLUMNW lvColumnHeader = { dwMask, dwFmt, 0, wszName, 0, 0, iImage, 0};
|
|
return (BOOL)SendMessage(m_hWnd, LVM_SETCOLUMNW, (WPARAM)iColumn, (LPARAM)&lvColumnHeader);
|
|
}
|
|
else
|
|
{
|
|
//Setup LVM_SETCOLUMN
|
|
CHAR szBuffer[MAX_NAME_LEN];
|
|
LV_COLUMNA lvColumnHeader = { dwMask, dwFmt, 0, szBuffer, 0, 0, iImage, 0};
|
|
ConvertToMBCS(wszName, szBuffer, MAX_NAME_LEN);
|
|
return (BOOL)SendMessage(m_hWnd, LVM_SETCOLUMNA, (WPARAM)iColumn, (LPARAM)&lvColumnHeader);
|
|
}
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CListViewLite::InsertColumn
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
INDEX CListViewLite::InsertColumn(INDEX iColumn, WCHAR* wszName, INT iImage)
|
|
{
|
|
return LV_InsertColumn(m_hWnd, iColumn, wszName, iImage);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CListViewLite::GetItemParam
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
LPARAM CListViewLite::GetItemParam(INDEX iItem)
|
|
{
|
|
return LV_GetItemParam(m_hWnd, iItem, 0);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CListViewLite::GetItemText
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
INDEX CListViewLite::GetItemText(INDEX iItem, INDEX iSubItem, WCHAR* wszName, ULONG ulMaxChars)
|
|
{
|
|
return LV_GetItemText(m_hWnd, iItem, iSubItem, wszName, ulMaxChars);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CListViewLite::HitTest
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
INDEX CListViewLite::HitTest(REFPOINTS pts, UINT* pFlags, BOOL fClientCoords)
|
|
{
|
|
LVHITTESTINFO lvHitInfo = {{pts.x, pts.y}, 0, 0};
|
|
if(!fClientCoords)
|
|
ScreenToClient(m_hWnd, &lvHitInfo.pt);
|
|
|
|
//LVM_HITTEST
|
|
INDEX iItem = (INDEX)SendMessage(m_hWnd, LVM_HITTEST, 0, (LPARAM)&lvHitInfo);
|
|
if(pFlags)
|
|
*pFlags = lvHitInfo.flags;
|
|
|
|
return iItem;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CTreeViewLite::CTreeViewLite
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
CTreeViewLite::CTreeViewLite(HWND hWndParent, UINT nID)
|
|
: CSplitterLite(hWndParent, nID)
|
|
{
|
|
m_hDraggingItem = NULL;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CTreeViewLite::~CTreeViewLite
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
CTreeViewLite::~CTreeViewLite()
|
|
{
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CTreeViewLite::OnCreate
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CTreeViewLite::OnCreate(CREATESTRUCT* pCREATESTRUCT)
|
|
{
|
|
//SubClass the window
|
|
SubClassWindow(WndProc);
|
|
|
|
//Delegate
|
|
return CSplitterLite::OnCreate(pCREATESTRUCT);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CTreeViewLite::OnNotify
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CTreeViewLite::OnNotify(INT idCtrl, NMHDR* pNMHDR)
|
|
{
|
|
switch(pNMHDR->code)
|
|
{
|
|
ON_COMMAND(TVN_SELCHANGED, OnSelChanged(idCtrl, (NMTREEVIEW*)pNMHDR));
|
|
ON_COMMAND(TVN_BEGINLABELEDIT, OnBeginLabelEdit(idCtrl, (NMTVDISPINFO*)pNMHDR));
|
|
ON_COMMAND(TVN_ENDLABELEDIT, OnEndLabelEdit(idCtrl, (NMTVDISPINFO*)pNMHDR));
|
|
ON_COMMAND(TVN_BEGINDRAG, OnBeginDrag(idCtrl, (NMTREEVIEW*)pNMHDR));
|
|
};
|
|
|
|
//Delegate
|
|
return CSplitterLite::OnNotify(idCtrl, pNMHDR);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CTreeViewLite::OnSelChanged
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
BOOL CTreeViewLite::OnSelChanged(INT idCtrl, NMTREEVIEW* pNMTreeView)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CTreeViewLite::OnBeginLabelEdit
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
BOOL CTreeViewLite::OnBeginLabelEdit(INT idCtrl, NMTVDISPINFO* ptvdi)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CTreeViewLite::OnEndLabelEdit
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
BOOL CTreeViewLite::OnEndLabelEdit(INT idCtrl, NMTVDISPINFO* ptvdi)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CTreeViewLite::OnBeginDrag
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
BOOL CTreeViewLite::OnBeginDrag(INT idCtrl, NMTREEVIEW* pNMTreeView)
|
|
{
|
|
//Tell the TreeView control to create an image to use for dragging.
|
|
HTREEITEM hItem = pNMTreeView->itemNew.hItem;
|
|
HIMAGELIST hImageList = TreeView_CreateDragImage(m_hWnd, hItem);
|
|
|
|
RECT rect;
|
|
TreeView_GetItemRect(m_hWnd, pNMTreeView->itemNew.hItem, &rect, FALSE);
|
|
m_hDraggingItem = hItem;
|
|
|
|
//Start the drag operation.
|
|
ULONG level = 0;
|
|
|
|
do
|
|
{
|
|
hItem = TreeView_GetParent(m_hWnd, hItem);
|
|
level++;
|
|
}
|
|
while(hItem);
|
|
|
|
LONG xIndent = TreeView_GetIndent( m_hWnd ) * level;
|
|
ImageList_BeginDrag(hImageList, 0, pNMTreeView->ptDrag.x - rect.left - xIndent, pNMTreeView->ptDrag.y - rect.top);
|
|
|
|
//Hide the mouse cursor, and direct mouse input to the parent window.
|
|
ShowCursor( FALSE );
|
|
SetCapture(m_hWnd);
|
|
|
|
ImageList_DragEnter(m_hWnd, pNMTreeView->ptDrag.x - rect.left - xIndent, pNMTreeView->ptDrag.y);
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CTreeViewLite::OnMouseMove
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CTreeViewLite::OnMouseMove(WPARAM nHittest, REFPOINTS pts)
|
|
{
|
|
if(m_hDraggingItem)
|
|
{
|
|
ImageList_DragMove(pts.x, pts.y);
|
|
|
|
//If the cursor is on an item, hilite it as the drop target
|
|
HTREEITEM hItem = HitTest(pts);
|
|
if(hItem)
|
|
{
|
|
ImageList_DragLeave( m_hWnd );
|
|
TreeView_SelectDropTarget(m_hWnd, hItem);
|
|
ImageList_DragEnter( m_hWnd, pts.x, pts.y);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CTreeViewLite::OnLButtonUp
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CTreeViewLite::OnLButtonUp(WPARAM fwKeys, REFPOINTS pts)
|
|
{
|
|
if(m_hDraggingItem)
|
|
{
|
|
//End the Drag
|
|
ImageList_EndDrag();
|
|
ReleaseCapture();
|
|
ShowCursor(TRUE);
|
|
ImageList_DragLeave( m_hWnd );
|
|
TreeView_SelectDropTarget(m_hWnd, NULL);
|
|
|
|
m_hDraggingItem = NULL;
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CTreeViewLite::GetItemParam
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
LPARAM CTreeViewLite::GetItemParam(HTREEITEM hTreeItem)
|
|
{
|
|
return TV_GetItemParam(m_hWnd, hTreeItem);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CTreeViewLite::SetItemState
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CTreeViewLite::SetItemState(HTREEITEM hItem, UINT iState, UINT iStateMask)
|
|
{
|
|
return TV_SetItemState(m_hWnd, hItem, iState, iStateMask);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CTreeViewLite::SetItemImage
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CTreeViewLite::SetItemImage(HTREEITEM hItem, INT iImage, INT iSelectedImage)
|
|
{
|
|
//TVM_SETITEM
|
|
TVITEM tvItem = { TVIF_IMAGE|TVIF_SELECTEDIMAGE, hItem, 0, 0, NULL, 0, iImage, iSelectedImage, 0, 0};
|
|
return (BOOL)SendMessage(m_hWnd, TVM_SETITEM, 0, (LPARAM)&tvItem);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CTreeViewLite::SetItemParam
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CTreeViewLite::SetItemParam(HTREEITEM hItem, LPARAM lParam)
|
|
{
|
|
//TVM_SETITEM
|
|
TVITEM tvItem = { TVIF_PARAM, hItem, 0, 0, NULL, 0, 0, 0, 0, lParam};
|
|
return (BOOL)SendMessage(m_hWnd, TVM_SETITEM, 0, (LPARAM)&tvItem);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CTreeViewLite::SetItemText
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CTreeViewLite::SetItemText(HTREEITEM hItem, WCHAR* pwszText)
|
|
{
|
|
if(IsUnicodeOS())
|
|
{
|
|
//TVM_SETITEM
|
|
TVITEMW tvItem = { TVIF_TEXT, hItem, 0, 0, pwszText, 0, 0, 0, 0, 0};
|
|
return (BOOL)SendMessageW(m_hWnd, TVM_SETITEMW, 0, (LPARAM)&tvItem);
|
|
}
|
|
else
|
|
{
|
|
CHAR szBuffer[MAX_NAME_LEN+1];
|
|
ConvertToMBCS(pwszText, szBuffer, MAX_NAME_LEN);
|
|
|
|
//TVM_SETITEM
|
|
TVITEMA tvItem = { TVIF_TEXT, hItem, 0, 0, szBuffer, 0, 0, 0, 0, 0};
|
|
return (BOOL)SendMessageA(m_hWnd, TVM_SETITEMA, 0, (LPARAM)&tvItem);
|
|
}
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// HTREEITEM CTreeViewLite::InsertItem
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
HTREEITEM CTreeViewLite::InsertItem(HTREEITEM hParent, HTREEITEM hInsAfter, WCHAR* wszName, LPARAM lParam, INT iImage, INT iSelectedImage, UINT iState, UINT iStateMask)
|
|
{
|
|
return TV_InsertItem(m_hWnd, hParent, hInsAfter, wszName, lParam, iImage, iSelectedImage, iState, iStateMask);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// HTREEITEM CTreeViewLite::HitTest
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
HTREEITEM CTreeViewLite::HitTest(REFPOINTS pts, UINT* pFlags, BOOL fClientCoords)
|
|
{
|
|
TVHITTESTINFO tvHitInfo = {{pts.x, pts.y}, 0, NULL};
|
|
if(!fClientCoords)
|
|
ScreenToClient(m_hWnd, &tvHitInfo.pt);
|
|
|
|
//TVM_HITTEST
|
|
HTREEITEM hItem = (HTREEITEM)SendMessage(m_hWnd, TVM_HITTEST, 0, (LPARAM)&tvHitInfo);
|
|
if(pFlags)
|
|
*pFlags = tvHitInfo.flags;
|
|
|
|
return hItem;
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CComboBoxLite::CComboBoxLite
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
CComboBoxLite::CComboBoxLite(HWND hWndParent, UINT nID)
|
|
: CWndLite(hWndParent, nID)
|
|
{
|
|
//NOTE: The "Height" of the combo indicates the "dropdown" height of the combo...
|
|
|
|
|
|
m_iSavedSel = CB_ERR;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CComboBoxLite::~CComboBoxLite
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
CComboBoxLite::~CComboBoxLite()
|
|
{
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CComboBoxLite::Populate
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
BOOL CComboBoxLite::Populate(ULONG cItems, const WIDENAMEMAP* rgItems)
|
|
{
|
|
//Remove any existing Data
|
|
ResetContent();
|
|
|
|
//Fill in the Combo Box...
|
|
for(ULONG i=0; i<cItems; i++)
|
|
AddString(rgItems[i].pwszName, (LPARAM)rgItems[i].lItem);
|
|
|
|
//Restore the Default Selection...
|
|
RestoreSelection();
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CComboBoxLite::OnCommandNotify
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
BOOL CComboBoxLite::OnCommandNotify(INT wNotifyCode, INT iID, HWND hWndCtrl)
|
|
{
|
|
switch(wNotifyCode)
|
|
{
|
|
case CBN_SELCHANGE:
|
|
{
|
|
if(OnSelChange(iID, hWndCtrl))
|
|
return TRUE;
|
|
break;
|
|
}
|
|
|
|
case CBN_DROPDOWN:
|
|
{
|
|
if(OnDropDown(iID, hWndCtrl))
|
|
return TRUE;
|
|
break;
|
|
}
|
|
};
|
|
|
|
//Otherwise Delegate
|
|
return CWndLite::OnCommandNotify(wNotifyCode, iID, hWndCtrl);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CComboBoxLite::OnSelChange
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
BOOL CComboBoxLite::OnSelChange(INT iID, HWND hWndCtrl)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CComboBoxLite::OnDropDown
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
BOOL CComboBoxLite::OnDropDown(INT iID, HWND hWndCtrl)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
// CComboBoxLite::AddString
|
|
//
|
|
/////////////////////////////////////////////////////////////////
|
|
INDEX CComboBoxLite::AddString(WCHAR* pwszString, LPARAM lParam)
|
|
{
|
|
//Delegate to our other function to add just the string to the combo
|
|
INDEX iItem = AddString(pwszString);
|
|
if(iItem!=CB_ERR)
|
|
{
|
|
//Now set the item data for this item...
|
|
SetItemParam(iItem, lParam);
|
|
}
|
|
|
|
return iItem;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CComboBoxLite::GetSelText
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
INDEX CComboBoxLite::GetSelText(WCHAR* pwszString, ULONG ulMaxSize)
|
|
{
|
|
ASSERT(pwszString);
|
|
ASSERT(ulMaxSize);
|
|
|
|
//Try to obtain the Current Selection
|
|
INDEX iSel = GetCurSel();
|
|
|
|
//This may fail, if the current selection is entered (DropDown instead of DropList)
|
|
if(iSel == CB_ERR)
|
|
{
|
|
GetWindowText(pwszString, ulMaxSize);
|
|
}
|
|
else
|
|
{
|
|
//Should be limiting the text if this ASSERT is hit!
|
|
//Length does not include the NULL Terminator
|
|
LRESULT ulLength = GetTextLength(iSel);
|
|
ASSERT((ULONG)ulLength < ulMaxSize);
|
|
|
|
//Obtain the text...
|
|
if((ULONG)ulLength < ulMaxSize)
|
|
GetText(iSel, pwszString);
|
|
}
|
|
|
|
return iSel;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
// CComboBoxLite::SetSelText
|
|
//
|
|
//////////////////////////////////////////////////////////////////
|
|
INDEX CComboBoxLite::SetSelText(WCHAR* pwszString, BOOL fAddItem)
|
|
{
|
|
ASSERT(pwszString);
|
|
|
|
//Try to find the Indicated Text
|
|
INDEX iSel = FindStringExact(pwszString);
|
|
|
|
//If not found, just add it to the list (if desired)
|
|
if(iSel == CB_ERR)
|
|
{
|
|
if(fAddItem)
|
|
{
|
|
iSel = AddString(pwszString, 0);
|
|
}
|
|
else
|
|
{
|
|
SetCurSel(iSel);
|
|
SetWindowText(pwszString);
|
|
}
|
|
}
|
|
|
|
if(iSel != CB_ERR)
|
|
iSel = SetCurSel(iSel);
|
|
|
|
return iSel;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
// CComboBoxLite::SetSelValue
|
|
//
|
|
/////////////////////////////////////////////////////////////////
|
|
INDEX CComboBoxLite::SetSelValue(LPARAM lParam)
|
|
{
|
|
//Loop through all Combo Item Values and Select specified one...
|
|
INDEX iCount = GetCount();
|
|
for(INDEX i=0; i<iCount; i++)
|
|
{
|
|
if(lParam == GetItemParam(i))
|
|
{
|
|
SetCurSel(i);
|
|
return i;
|
|
}
|
|
}
|
|
|
|
return CB_ERR;
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CComboBoxLite::GetSelValue
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
LPARAM CComboBoxLite::GetSelValue()
|
|
{
|
|
//Obtain the Current Selection
|
|
INDEX iSel = GetCurSel();
|
|
LPARAM lParam = CB_ERR;
|
|
|
|
//This may fail, if the current selection is entered (DropDown instead of DropList)
|
|
if(iSel == CB_ERR)
|
|
{
|
|
WCHAR* pwszText = GetWindowText();
|
|
WCHAR* pwszEnd = NULL;
|
|
if(pwszText)
|
|
{
|
|
//Convert to LPARAM
|
|
if(!ConvertToLONG(pwszText, (LONG*)&lParam))
|
|
lParam = CB_ERR;
|
|
SAFE_FREE(pwszText);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
lParam = GetItemParam(iSel);
|
|
}
|
|
|
|
return lParam;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CButtonLite::CButtonLite
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
CButtonLite::CButtonLite(HWND hWndParent, UINT nID)
|
|
: CWndLite(hWndParent, nID)
|
|
{
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CButtonLite::~CButtonLite
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
CButtonLite::~CButtonLite()
|
|
{
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CComboBoxEx::CComboBoxEx
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
CComboBoxEx::CComboBoxEx(HWND hWndParent, UINT nID)
|
|
: CComboBoxLite(hWndParent, nID)
|
|
{
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CComboBoxEx::~CComboBoxEx
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
CComboBoxEx::~CComboBoxEx()
|
|
{
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CComboBoxEx::OnInitialUpdate
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CComboBoxEx::OnInitialUpdate()
|
|
{
|
|
SetUnicodeFormat(IsUnicodeOS());
|
|
|
|
//Delegate
|
|
return CComboBoxLite::OnInitialUpdate();
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CComboBoxEx::InsertItem
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
INDEX CComboBoxEx::InsertItem(INDEX iItem, WCHAR* pwszName, LPARAM lParam, INT iIndent, INT iImage, UINT iSelectedImage)
|
|
{
|
|
INDEX iIndex = CB_ERR;
|
|
|
|
//Figure out the mask
|
|
UINT dwMask = 0;
|
|
if(lParam != PARAM_NONE)
|
|
dwMask |= CBEIF_LPARAM;
|
|
if(pwszName )
|
|
dwMask |= CBEIF_TEXT;
|
|
if(iIndent != PARAM_NONE)
|
|
dwMask |= CBEIF_INDENT;
|
|
if(iImage != IMAGE_NONE)
|
|
dwMask |= CBEIF_IMAGE;
|
|
if(iSelectedImage != IMAGE_NONE)
|
|
dwMask |= CBEIF_SELECTEDIMAGE;
|
|
|
|
//CBEM_INSERTITEM
|
|
//NOTE: In the OnInitialUpdate we set the ComboBoxEx to be Unicode if on
|
|
//a unicode OS and ANSI is not. Even thought resource has ComboBoxEx (ANSI) the control
|
|
//allow the user tha change the setting at runtime...
|
|
if(IsUnicodeOS())
|
|
{
|
|
COMBOBOXEXITEMW comboItem = { dwMask, iItem, pwszName, 0/*cchTextMax*/, iImage, iSelectedImage, 0/*iOverlay*/, iIndent, lParam };
|
|
iIndex = SendMessageW(m_hWnd, CBEM_INSERTITEMW, 0, (LPARAM)&comboItem);
|
|
}
|
|
else
|
|
{
|
|
CHAR szBuffer[MAX_NAME_LEN+1]={0};
|
|
ConvertToMBCS(pwszName, szBuffer, MAX_NAME_LEN);
|
|
|
|
COMBOBOXEXITEMA comboItem = { dwMask, iItem, szBuffer, 0/*cchTextMax*/, iImage, iSelectedImage, 0/*iOverlay*/, iIndent, lParam };
|
|
iIndex = SendMessageA(m_hWnd, CBEM_INSERTITEMA, 0, (LPARAM)&comboItem);
|
|
}
|
|
|
|
return iIndex;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CToolBarLite::CToolBarLite
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
CToolBarLite::CToolBarLite()
|
|
{
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CToolBarLite::~CToolBarLite
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
CToolBarLite::~CToolBarLite()
|
|
{
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CToolBarLite::Create
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CToolBarLite::Create(HWND hWndParent, UINT nID, UINT nBitmapID, UINT cButtons, TBBUTTON* rgButtons, DWORD dwStyle)
|
|
{
|
|
ASSERT(IsDestroyed());
|
|
m_hWndParent = hWndParent;
|
|
HINSTANCE hInstance = GetAppLite()->m_hInstance;
|
|
|
|
//Create ToolBar
|
|
m_hWnd = CreateToolbarEx(
|
|
hWndParent, // parent
|
|
dwStyle,
|
|
nID, // toolbar id
|
|
3, // number of bitmaps
|
|
hInstance, // mod instance
|
|
nBitmapID, // resource ID for bitmap
|
|
rgButtons, // address of buttons
|
|
cButtons, // number of buttons
|
|
16,16, // width & height of buttons
|
|
16,16, // width & height of bitmaps
|
|
sizeof(TBBUTTON)); // structure size
|
|
|
|
//Create ToolTips
|
|
HWND hWndTT = (HWND)SendMessage(m_hWnd, TB_GETTOOLTIPS, 0, 0);
|
|
if(hWndTT)
|
|
{
|
|
TOOLINFOA toolInfo;
|
|
memset(&toolInfo, 0, sizeof(TOOLINFO));
|
|
toolInfo.cbSize = sizeof(TOOLINFO);
|
|
toolInfo.uFlags = TTF_CENTERTIP;
|
|
toolInfo.hwnd = m_hWnd;
|
|
toolInfo.uId = (UINT)ID_TOOLBAR;
|
|
toolInfo.hinst = hInstance;
|
|
toolInfo.lpszText = (LPSTR)LPSTR_TEXTCALLBACKA;
|
|
|
|
// Set up the ToolTips
|
|
SendMessage(hWndTT, TTM_ADDTOOLA, 0, (LPARAM)&toolInfo);
|
|
}
|
|
return m_hWnd != NULL;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CStatusBarLite::CStatusBarLite
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
CStatusBarLite::CStatusBarLite()
|
|
{
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CStatusBarLite::~CStatusBarLite
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
CStatusBarLite::~CStatusBarLite()
|
|
{
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CStatusBarLite::Create
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CStatusBarLite::Create(HWND hWndParent, UINT nID, WCHAR* pwszText, DWORD dwStyle)
|
|
{
|
|
ASSERT(IsDestroyed());
|
|
m_hWndParent = hWndParent;
|
|
|
|
//Create StatusBar
|
|
if(IsUnicodeOS())
|
|
{
|
|
m_hWnd = CreateStatusWindowW(dwStyle, pwszText, hWndParent, nID);
|
|
}
|
|
else
|
|
{
|
|
CHAR szBuffer[MAX_NAME_LEN];
|
|
ConvertToMBCS(pwszText, szBuffer, MAX_NAME_LEN);
|
|
m_hWnd = CreateStatusWindowA(dwStyle, szBuffer, hWndParent, nID);
|
|
}
|
|
|
|
return m_hWnd != NULL;
|
|
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CPropPageLite::CPropPageLite
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
CPropPageLite::CPropPageLite(UINT uIDD, TCHAR* ptszTitle)
|
|
: CDialogLite(uIDD)
|
|
{
|
|
memset(&m_psPage, 0, sizeof(PROPSHEETPAGE));
|
|
|
|
//PROPSHEETPAGE
|
|
m_psPage.dwSize = sizeof(PROPSHEETPAGE);
|
|
m_psPage.dwFlags = PSP_USETITLE;
|
|
m_psPage.hInstance = GetAppLite()->m_hInstance;
|
|
m_psPage.pszTemplate = MAKEINTRESOURCE(uIDD);
|
|
m_psPage.pszIcon = NULL;
|
|
m_psPage.pfnDlgProc = PropPageProc;
|
|
m_psPage.pszTitle = ptszTitle;
|
|
m_psPage.lParam = (INT_PTR)this;
|
|
|
|
//Parent Property Sheet
|
|
m_pCPropSheet = NULL;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CPropPageLite::~CPropPageLite
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
CPropPageLite::~CPropPageLite()
|
|
{
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CPropPageLite::CPropPageLite
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
void CPropPageLite::SetParent(CPropSheetLite* pCPropSheetLite)
|
|
{
|
|
ASSERT(pCPropSheetLite);
|
|
m_pCPropSheet = pCPropSheetLite;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CPropPageLite::OnApply
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CPropPageLite::OnApply()
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CPropPageLite::OnOK
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CPropPageLite::OnOK()
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CPropPageLite::OnReset
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CPropPageLite::OnReset()
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CPropPageLite::OnCancel
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CPropPageLite::OnCancel()
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CPropPageLite::OnSetActive
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CPropPageLite::OnSetActive()
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CPropPageLite::OnKillActive
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CPropPageLite::OnKillActive()
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CPropPageLite::HandleMessage
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CPropPageLite::HandleMessage(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
switch(msg)
|
|
{
|
|
case WM_NOTIFY:
|
|
{
|
|
switch (((NMHDR*)lParam)->code)
|
|
{
|
|
case PSN_SETACTIVE:
|
|
{
|
|
if(!OnSetActive())
|
|
{
|
|
SetWindowLongPtr(hWnd, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE);
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
case PSN_KILLACTIVE:
|
|
{
|
|
if(!OnKillActive())
|
|
{
|
|
SetWindowLongPtr(hWnd, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE);
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
case PSN_APPLY: //OK
|
|
{
|
|
if(!OnApply())
|
|
{
|
|
SetWindowLongPtr(hWnd, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE);
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
case PSN_RESET: //CANCEL
|
|
OnReset();
|
|
return FALSE;
|
|
}
|
|
}
|
|
};
|
|
|
|
//Pass the message onto the Dialog
|
|
return CDialogLite::HandleMessage(hWnd, msg, wParam, lParam);
|
|
}
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CPropPageLite::PropPageProc
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
INT_PTR WINAPI CPropPageLite::PropPageProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
CPropPageLite* pCPropPageLite = (CPropPageLite*)GetThis(hWnd);
|
|
|
|
switch(msg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
{
|
|
//Save the Window Handle
|
|
PROPSHEETPAGE*ps = (PROPSHEETPAGE*)lParam;
|
|
CPropPageLite* pCPropPageLite = (CPropPageLite*)ps->lParam;
|
|
pCPropPageLite->m_hWnd = hWnd;
|
|
|
|
//Save the "this" pointer
|
|
SetThis(hWnd, pCPropPageLite);
|
|
return pCPropPageLite->OnInitDialog();
|
|
}
|
|
};
|
|
|
|
if(pCPropPageLite)
|
|
return pCPropPageLite->HandleMessage(hWnd, msg, wParam, lParam);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CPropSheetLite::CPropSheetLite
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
CPropSheetLite::CPropSheetLite(TCHAR* ptszTitle, HICON hIcon)
|
|
{
|
|
memset(&m_psHeader, 0, sizeof(PROPSHEETPAGE));
|
|
|
|
//PROPSHEETHEADER
|
|
m_psHeader.dwSize = sizeof(PROPSHEETHEADER);
|
|
m_psHeader.dwFlags = PSH_USEHICON | PSH_PROPSHEETPAGE | PSH_NOAPPLYNOW;
|
|
m_psHeader.hwndParent = NULL;
|
|
m_psHeader.hInstance = GetAppLite()->m_hInstance;
|
|
m_psHeader.hIcon = hIcon;
|
|
m_psHeader.pszCaption = ptszTitle;
|
|
m_psHeader.nPages = 0;
|
|
m_psHeader.nStartPage = 0;
|
|
m_psHeader.ppsp = NULL;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CPropSheetLite::~CPropSheetLite
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
CPropSheetLite::~CPropSheetLite()
|
|
{
|
|
SAFE_FREE(m_psHeader.ppsp);
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CPropSheetLite::AddPage
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
void CPropSheetLite::AddPage(CPropPageLite* pCPropPageLite)
|
|
{
|
|
ASSERT(pCPropPageLite);
|
|
HRESULT hr = S_OK;
|
|
|
|
//Set the Pages parent (this sheet)
|
|
pCPropPageLite->SetParent(this);
|
|
|
|
//Enlarge the array
|
|
SAFE_REALLOC(m_psHeader.ppsp, PROPSHEETPAGE, m_psHeader.nPages+1);
|
|
|
|
//Copy into our array
|
|
memcpy((void*)&m_psHeader.ppsp[m_psHeader.nPages], &pCPropPageLite->m_psPage, sizeof(PROPSHEETPAGE));
|
|
m_psHeader.nPages++;
|
|
|
|
CLEANUP:
|
|
;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CPropSheetLite::DoModal
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
LRESULT CPropSheetLite::DoModal(HWND hWndParent, INT nStartPage)
|
|
{
|
|
//Display the Property Sheet
|
|
m_psHeader.hwndParent = hWndParent;
|
|
m_psHeader.nStartPage = nStartPage;
|
|
return PropertySheet(&m_psHeader);
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CTabLite::CTabLite
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
CTabLite::CTabLite(HWND hWndParent, UINT nID)
|
|
: CSplitterLite(hWndParent, nID)
|
|
{
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CTabLite::~CTabLite
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
CTabLite::~CTabLite()
|
|
{
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CTabLite::OnCreate
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CTabLite::OnCreate(CREATESTRUCT* pCREATESTRUCT)
|
|
{
|
|
//SubClass the window
|
|
SubClassWindow(WndProc);
|
|
|
|
//Delegate
|
|
return CSplitterLite::OnCreate(pCREATESTRUCT);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CTabLite::OnNotify
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CTabLite::OnNotify(INT idCtrl, NMHDR* pNMHDR)
|
|
{
|
|
switch(pNMHDR->code)
|
|
{
|
|
ON_COMMAND(TCN_SELCHANGE, OnSelChange((INT)pNMHDR->idFrom, pNMHDR->hwndFrom));
|
|
ON_COMMAND(TCN_SELCHANGING, OnSelChanging((INT)pNMHDR->idFrom, pNMHDR->hwndFrom));
|
|
// ON_COMMAND(TCN_GETOBJECT, OnGetObject((NMOBJECTNOTIFY*)pNMHDR));
|
|
};
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CTabLite::SetCurSel
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
INDEX CTabLite::SetCurSel(INDEX iItem, BOOL fSendNotification)
|
|
{
|
|
//NOTE: We have to send this message our selves due to the following MSDN Article
|
|
//"This method selects a tab in a tab control. A tab control does not send a
|
|
//TCN_SELCHANGING or TCN_SELCHANGE notification message when a tab is selected using
|
|
//this method. These notifications are sent, using WM_NOTIFY, when the user clicks or
|
|
//uses the keyboard to change tabs."
|
|
if(fSendNotification)
|
|
{
|
|
NMHDR nmHdr = { m_hWnd, IDP_TABS, TCN_SELCHANGING };
|
|
SendMessage(m_hWnd, WM_NOTIFY, 0, (LPARAM)&nmHdr);
|
|
}
|
|
|
|
//Send the message
|
|
INDEX iSel = (INDEX)::SendMessageA(m_hWnd, TCM_SETCURSEL, iItem, 0);
|
|
|
|
//Post
|
|
if(fSendNotification)
|
|
{
|
|
NMHDR nmHdr = { m_hWnd, IDP_TABS, TCN_SELCHANGE };
|
|
SendMessage(m_hWnd, WM_NOTIFY, 0, (LPARAM)&nmHdr);
|
|
}
|
|
|
|
return iSel;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CTabLite::OnSelChange
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
BOOL CTabLite::OnSelChange(INT iID, HWND hWndCtrl)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CTabLite::OnSelChanging
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
BOOL CTabLite::OnSelChanging(INT iID, HWND hWndCtrl)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
// CTabLite::FindTab
|
|
//
|
|
/////////////////////////////////////////////////////////////////
|
|
INDEX CTabLite::FindTab(LPARAM lParam)
|
|
{
|
|
//Try and find this suite in the list
|
|
INDEX cItems = GetItemCount();
|
|
for(INDEX iItem=0; iItem<cItems; iItem++)
|
|
{
|
|
LPARAM lCurParam = GetItemData(iItem);
|
|
if(lParam == lCurParam)
|
|
return iItem;
|
|
}
|
|
|
|
return CB_ERR;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CTabLite::GetItemData
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
LPARAM CTabLite::GetItemData(INDEX iItem)
|
|
{
|
|
LPARAM lParam = CB_ERR;
|
|
|
|
//Delegate
|
|
if(GetItem(iItem, NULL, 0, &lParam))
|
|
return lParam;
|
|
|
|
return CB_ERR;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CTabLite::GetItem
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CTabLite::GetItem(INDEX iItem, WCHAR* pwszText, ULONG ulMaxLength, LPARAM* plParam)
|
|
{
|
|
//Calculate the Mask/flags
|
|
UINT dwMask = 0;
|
|
if(pwszText && ulMaxLength)
|
|
dwMask |= TCIF_TEXT;
|
|
// if(iImage != IMAGE_NONE)
|
|
// dwMask |= TCIF_IMAGE;
|
|
// if(dwState != STATE_NONE)
|
|
// dwMask |= TCIF_STATE;
|
|
if(plParam)
|
|
dwMask |= TCIF_PARAM;
|
|
|
|
if(IsUnicodeOS())
|
|
{
|
|
//TCM_GETITEMW
|
|
TCITEMW tcItem = { dwMask, 0, 0, pwszText, ulMaxLength, 0, 0/*lParam*/};
|
|
if(SendMessageW(m_hWnd, TCM_GETITEMW, iItem, (LPARAM)&tcItem))
|
|
{
|
|
if(plParam)
|
|
*plParam = tcItem.lParam;
|
|
return TRUE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
CHAR szBuffer[MAX_NAME_LEN+1];
|
|
|
|
//TCM_GETITEMA
|
|
TCITEMA tcItem = { dwMask, 0, 0, szBuffer, MAX_NAME_LEN, 0, 0/*lParam*/};
|
|
if(SendMessageA(m_hWnd, TCM_GETITEMA, iItem, (LPARAM)&tcItem))
|
|
{
|
|
if(pwszText)
|
|
ConvertToWCHAR(szBuffer, pwszText, ulMaxLength);
|
|
if(plParam)
|
|
*plParam = tcItem.lParam;
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
|
|
//Otherwise
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CTabLite::SetItemText
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CTabLite::SetItemText(INDEX iItem, LPCWSTR pwszText)
|
|
{
|
|
//Delegate
|
|
return SetItem(iItem, pwszText);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CTabLite::SetItem
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CTabLite::SetItem(INDEX iItem, LPCWSTR pwszText, LPARAM lParam, INT iImage, DWORD dwState, DWORD dwStateMask)
|
|
{
|
|
//Calculate the Mask/flags
|
|
UINT dwMask = 0;
|
|
if(pwszText)
|
|
dwMask |= TCIF_TEXT;
|
|
if(iImage != IMAGE_NONE)
|
|
dwMask |= TCIF_IMAGE;
|
|
if(dwState != STATE_NONE)
|
|
dwMask |= TCIF_STATE;
|
|
if(lParam != PARAM_NONE)
|
|
dwMask |= TCIF_PARAM;
|
|
|
|
if(IsUnicodeOS())
|
|
{
|
|
//TVM_SETITEM
|
|
TCITEMW tcItem = { dwMask, dwState, dwStateMask, (WCHAR*)pwszText, 0/*cchTextMax*/, iImage, lParam };
|
|
return (BOOL)SendMessageW(m_hWnd, TCM_SETITEMW, iItem, (LPARAM)&tcItem);
|
|
}
|
|
else
|
|
{
|
|
CHAR szBuffer[MAX_NAME_LEN+1];
|
|
ConvertToMBCS(pwszText, szBuffer, MAX_NAME_LEN);
|
|
|
|
//TVM_SETITEM
|
|
TCITEMA tcItem = { dwMask, dwState, dwStateMask, szBuffer, 0/*cchTextMax*/, iImage, lParam };
|
|
return (BOOL)SendMessageA(m_hWnd, TCM_SETITEMA, iItem, (LPARAM)&tcItem);
|
|
}
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CTabLite::InsertItem
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
INDEX CTabLite::InsertItem(INDEX iItem, LPCWSTR pwszText, LPARAM lParam, INT iImage, DWORD dwState, DWORD dwStateMask)
|
|
{
|
|
//Calculate the Mask/flags
|
|
UINT dwMask = 0;
|
|
if(pwszText)
|
|
dwMask |= TCIF_TEXT;
|
|
if(iImage != IMAGE_NONE)
|
|
dwMask |= TCIF_IMAGE;
|
|
if(dwState != STATE_NONE)
|
|
dwMask |= TCIF_STATE;
|
|
if(lParam != PARAM_NONE)
|
|
dwMask |= TCIF_PARAM;
|
|
|
|
if(IsUnicodeOS())
|
|
{
|
|
//TCM_INSERTITEM
|
|
TCITEMW tcItem = { dwMask, dwState, dwStateMask, (WCHAR*)pwszText, 0/*cchTextMax*/, iImage, lParam };
|
|
return (INDEX)SendMessageW(m_hWnd, TCM_INSERTITEMW, iItem, (LPARAM)&tcItem);
|
|
}
|
|
else
|
|
{
|
|
CHAR szBuffer[MAX_QUERY_LEN+1] = {0};
|
|
ConvertToMBCS(pwszText, szBuffer, MAX_QUERY_LEN);
|
|
|
|
//TCM_INSERTITEM
|
|
TCITEMA tcItem = { dwMask, dwState, dwStateMask, szBuffer, 0/*cchTextMax*/, iImage, lParam };
|
|
return (INDEX)SendMessageA(m_hWnd, TCM_INSERTITEMA, iItem, (LPARAM)&tcItem);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CCmdLineLite
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
CCmdLineLite::CCmdLineLite()
|
|
{
|
|
m_wszLastCmd[0] = wEOL;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CCmdLineLite
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
CCmdLineLite::~CCmdLineLite()
|
|
{
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CCmdLineLite::ResetParser
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void CCmdLineLite::ResetParser()
|
|
{
|
|
m_wszLastCmd[0] = wEOL;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CCmdLineLite::ParseParam
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void CCmdLineLite::ParseParam( WCHAR* pwszParam, BOOL bFlag, BOOL bLast )
|
|
{
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CCmdLineLite::ParseCommandLine
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
BOOL CCmdLineLite::ParseCommandLine()
|
|
{
|
|
//NOTE: This is a simple command line parser which relies upon the Runtime to seperate
|
|
//the arguments into argc/argv pairs. Basically the runtime determines arguments by words
|
|
//seperated soley by spaces, unless they are enclosed in double quotes. If an argument
|
|
//has spaces or needs embedded quotes, you need to close the argument in double quotes
|
|
//and the embedded quotes need to be single quotes, (as single quotes are not recognized
|
|
//and are ignored)
|
|
WCHAR wszBuffer[MAX_QUERY_LEN];
|
|
|
|
for(INT i=1; i<__argc; i++)
|
|
{
|
|
//TODO remove conversion code for NT unicode support (GetCommandLineW)
|
|
//Can always do the opposite conversion on Win95 if only GetCommandLineA is supported.
|
|
WCHAR* pwszParam = wszBuffer;
|
|
ConvertToWCHAR(__argv[i], pwszParam, MAX_QUERY_LEN);
|
|
|
|
BOOL bFlag = FALSE;
|
|
BOOL bLast = ((i + 1) == __argc);
|
|
if(pwszParam[0] == L'-' || pwszParam[0] == L'/')
|
|
{
|
|
// remove flag specifier
|
|
bFlag = TRUE;
|
|
pwszParam++;
|
|
}
|
|
|
|
ParseParam(pwszParam, bFlag, bLast);
|
|
}
|
|
|
|
//TRUE - CmdLine specified, FALSE - no command line args
|
|
return __argc >1;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CCmdLineLite::ParseFile
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
BOOL CCmdLineLite::ParseFile(WCHAR* pwszFileName)
|
|
{
|
|
if(!pwszFileName)
|
|
return FALSE;
|
|
|
|
static CHAR szBuffer[MAX_QUERY_LEN+1] = {0};
|
|
CHAR* pszToken = NULL;
|
|
BOOL bFlag = TRUE;
|
|
|
|
//Reset the Parser
|
|
ResetParser();
|
|
|
|
//Open the file - for reading...
|
|
CFileLite cFile;
|
|
if(FAILED(cFile.Open(pwszFileName, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING)))
|
|
return FALSE;
|
|
|
|
//Start reading...
|
|
//NOTE: We read the entire steam in ANSI, since this is the native format of the file.
|
|
//We get major speed improvements reading all characters first, then converting to Unicode.
|
|
//This method also prevens bugs with converting MBCS chars to unicode when all the characters
|
|
//have not been read, since we may be converting and leading or trailing byte independent
|
|
//of the context or other characters related...
|
|
while(!cFile.IsEOF())
|
|
{
|
|
CHAR chToken = 0;
|
|
CHAR chQuote = 0;
|
|
LONG cQuotes = 0;
|
|
ULONG cChars = 0;
|
|
BOOL bLast = FALSE;
|
|
|
|
szBuffer[0] = EOL;
|
|
pszToken = szBuffer;
|
|
|
|
//Obtain the string
|
|
//Sure wish getLine allowed more than 1 deliminator
|
|
//Since its doesn't I get 1 character at a time until either a space
|
|
//or carriage return it hit...
|
|
while(!cFile.IsEOF() && cChars<MAX_QUERY_LEN)
|
|
{
|
|
if(cFile.Read(sizeof(CHAR), &chToken)!=S_OK)
|
|
break;
|
|
|
|
//Quote Character
|
|
if(chToken == '\"' || chToken == '\'')
|
|
{
|
|
//First Quote - remember which quote char used
|
|
if(cQuotes==0 && cChars==0)
|
|
chQuote = chToken;
|
|
|
|
//Start or End of Quote
|
|
if(chToken == chQuote)
|
|
cQuotes = cQuotes ? cQuotes-1 : cQuotes+1;
|
|
|
|
//Don't include the first or the last quote
|
|
if(cChars==0 || cQuotes==0)
|
|
continue;
|
|
}
|
|
|
|
//End of Token
|
|
if(cQuotes==0)
|
|
{
|
|
//End of Token indicators (not inside quotes)
|
|
if(chToken==' ' || chToken=='\n' || cFile.IsEOF())
|
|
break;
|
|
|
|
//Line Feed are ignored (not inside quotes)
|
|
if(chToken=='\r')
|
|
continue;
|
|
}
|
|
|
|
*pszToken = chToken;
|
|
pszToken++;
|
|
cChars++;
|
|
}
|
|
|
|
//End of this token...
|
|
*pszToken = EOL;
|
|
|
|
//Determine if this is a flag or parameter
|
|
//Its only a flag if it wasn't inside a quoted option and begins with '/' or '-'
|
|
if(!chQuote && (szBuffer[0] == '/' || szBuffer[0] == '-'))
|
|
{
|
|
bFlag = TRUE; //This is a flag
|
|
pszToken = &szBuffer[1]; //Remove the flag
|
|
}
|
|
else
|
|
{
|
|
bFlag = FALSE;
|
|
pszToken = szBuffer;
|
|
}
|
|
|
|
//Last Argument in the file...
|
|
bLast = cFile.IsEOF();
|
|
|
|
//Parse The Command Line...
|
|
//Ignore whitespace, but whitespace enclosed in quotes is counted as a param...
|
|
if(pszToken[0] || chQuote)
|
|
{
|
|
//Now convert the Token into Unicode...
|
|
static WCHAR wszBuffer[MAX_QUERY_LEN] = {0};
|
|
ConvertToWCHAR(pszToken, wszBuffer, MAX_QUERY_LEN);
|
|
|
|
//Parse this parameter...
|
|
ParseParam(wszBuffer, bFlag, bLast);
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CFileLite
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
CFileLite::CFileLite()
|
|
{
|
|
m_hFile = NULL;
|
|
m_bEOF = FALSE;
|
|
|
|
m_bUnicode = FALSE;
|
|
m_cbWritten = 0;
|
|
m_cbRead = 0;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// ~CFileLite
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
CFileLite::~CFileLite()
|
|
{
|
|
//Cannot Call Virtual function from destructor
|
|
CFileLite::Close();
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CFileLite::Open
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
HRESULT CFileLite::Open(LPCWSTR pwszFileName, DWORD dwDesiredAccess, DWORD dwShareMode, DWORD dwCreationDisposition, BOOL fDisplayDialog, HWND hWndParent)
|
|
{
|
|
ASSERT(m_hFile == NULL);
|
|
|
|
if(IsUnicodeOS())
|
|
{
|
|
m_hFile = CreateFileW
|
|
(
|
|
pwszFileName,
|
|
dwDesiredAccess, // access (read-write) mode
|
|
dwShareMode, // share mode
|
|
NULL, // pointer to security attributes
|
|
dwCreationDisposition, // how to create
|
|
FILE_ATTRIBUTE_NORMAL, // file attributes
|
|
NULL // handle to file with attributes to copy
|
|
);
|
|
|
|
if(m_hFile==INVALID_HANDLE_VALUE)
|
|
{
|
|
if(fDisplayDialog)
|
|
{
|
|
wMessageBox(hWndParent, MB_TASKMODAL | MB_ICONERROR | MB_OK, wsz_ERROR, L"Unable to open file \"%s\", make sure File Name and Path are valid", pwszFileName);
|
|
if(hWndParent)
|
|
SetFocus(hWndParent);
|
|
}
|
|
m_hFile = NULL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
static CHAR szFileName[MAX_NAME_LEN] = {0};
|
|
ConvertToMBCS(pwszFileName, szFileName, MAX_NAME_LEN);
|
|
|
|
//Delegate
|
|
return Open(szFileName, dwDesiredAccess, dwShareMode, dwCreationDisposition,
|
|
fDisplayDialog, hWndParent);
|
|
}
|
|
|
|
return m_hFile ? S_OK : E_FAIL;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CFileLite::Open
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
HRESULT CFileLite::Open(LPCSTR pszFileName, DWORD dwDesiredAccess, DWORD dwShareMode, DWORD dwCreationDisposition, BOOL fDisplayDialog, HWND hWndParent)
|
|
{
|
|
ASSERT(m_hFile == NULL);
|
|
|
|
m_hFile = CreateFileA
|
|
(
|
|
pszFileName,
|
|
dwDesiredAccess, // access (read-write) mode
|
|
dwShareMode, // share mode
|
|
NULL, // pointer to security attributes
|
|
dwCreationDisposition, // how to create
|
|
FILE_ATTRIBUTE_NORMAL, // file attributes
|
|
NULL // handle to file with attributes to copy
|
|
);
|
|
|
|
if(m_hFile==INVALID_HANDLE_VALUE)
|
|
{
|
|
if(fDisplayDialog)
|
|
{
|
|
wMessageBox(hWndParent, MB_TASKMODAL | MB_ICONERROR | MB_OK, wsz_ERROR, L"Unable to open file \"%S\", make sure File Name and Path are valid", pszFileName);
|
|
if(hWndParent)
|
|
SetFocus(hWndParent);
|
|
}
|
|
m_hFile = NULL;
|
|
}
|
|
|
|
return m_hFile ? S_OK : E_FAIL;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CFileLite::Seek
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
DWORD CFileLite::Seek(LONG lDistanceToMove, DWORD dwOrigin)
|
|
{
|
|
if(m_hFile)
|
|
return SetFilePointer(m_hFile, lDistanceToMove, NULL, dwOrigin);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CFileLite::DetermineUnicode
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CFileLite::DetermineUnicode()
|
|
{
|
|
//When you open a file in Notepad, Notepad calls a Win32 function named IsTextUnicode.
|
|
//This function determines whether the file uses Unicode. If the file starts with the
|
|
//conventional signature for Unicode the BOM U+FEFF it knows to treat the file as Unicode.
|
|
//(Notepad always adds a BOM to a Unicode file when saving it and hides it again when opening
|
|
//the file.) If there is no BOM, IsTextUnicode can only guess whether the file uses Unicode
|
|
//based on a number of rules (described in the Visual C++ 2 documentation of IsTextUnicode).
|
|
if(!m_cbRead)
|
|
{
|
|
//If we have not read any characters yet, we need to read the first 2 characters
|
|
//(which may contain the BOM - Byte Order Mark) to determine if unicode or MBCS format
|
|
WCHAR wBOM = wEOL;
|
|
if(ReadFile(m_hFile, &wBOM, sizeof(wBOM), &m_cbRead, NULL))
|
|
{
|
|
if(wBOM == UNICODE_BYTE_ORDER_MARK)
|
|
{
|
|
//Unicode file
|
|
m_bUnicode = TRUE;
|
|
}
|
|
else
|
|
{
|
|
//Otherwise its not Unicode, and the bytes we just read are real
|
|
//data, so "unread" them by moving the seek pointer back...
|
|
Seek(-(LONG)m_cbRead, FILE_CURRENT);
|
|
m_bUnicode = FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
return m_bUnicode;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CFileLite::Read
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
HRESULT CFileLite::Read(ULONG cbBytes, WCHAR* pwszText, ULONG* pcbRead)
|
|
{
|
|
ULONG cbRead = 0;
|
|
HRESULT hr = S_OK;
|
|
|
|
if(m_hFile && pwszText)
|
|
{
|
|
if(DetermineUnicode())
|
|
{
|
|
//The file is Unicode, just read directly into unicode string
|
|
hr = ReadBytes(cbBytes, (BYTE*)pwszText, &cbRead);
|
|
}
|
|
else
|
|
{
|
|
static CHAR szBuffer[MAX_QUERY_LEN] = {0};
|
|
|
|
//The file is MBCS, conversion is required to Unicode string
|
|
hr = ReadBytes(min(cbBytes/2, sizeof(szBuffer)), (BYTE*)szBuffer, &cbRead);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
ConvertToWCHAR(szBuffer, pwszText, cbBytes);
|
|
cbRead = cbRead*sizeof(WCHAR);
|
|
}
|
|
}
|
|
}
|
|
|
|
if(pcbRead)
|
|
*pcbRead = cbRead;
|
|
return hr;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CFileLite::Read
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
HRESULT CFileLite::Read(ULONG cbBytes, CHAR* pszText, ULONG* pcbRead)
|
|
{
|
|
ULONG cbRead = 0;
|
|
HRESULT hr = S_OK;
|
|
|
|
if(m_hFile && pszText)
|
|
{
|
|
if(DetermineUnicode())
|
|
{
|
|
static WCHAR wszBuffer[MAX_QUERY_LEN] = {0};
|
|
|
|
//The file is Unicode, conversion is required to MBCS string
|
|
hr = ReadBytes(min(cbBytes*2, sizeof(wszBuffer)), (BYTE*)wszBuffer, &cbRead);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
ConvertToMBCS(wszBuffer, pszText, cbBytes);
|
|
cbRead = cbRead/sizeof(WCHAR);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//The file is MBCS, just read directly from the stream
|
|
hr = ReadBytes(cbBytes, (BYTE*)pszText, &cbRead);
|
|
}
|
|
}
|
|
|
|
if(pcbRead)
|
|
*pcbRead = cbRead;
|
|
return hr;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CFileLite::ReadBytes
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
HRESULT CFileLite::ReadBytes(ULONG cbBytes, BYTE* rgBytes, ULONG* pcbRead)
|
|
{
|
|
ULONG cbRead = 0;
|
|
HRESULT hr = S_OK;
|
|
|
|
if(m_hFile && cbBytes)
|
|
{
|
|
ASSERT(rgBytes);
|
|
|
|
//Read from the file...
|
|
if(ReadFile(m_hFile, rgBytes, cbBytes, &cbRead, NULL))
|
|
{
|
|
if(cbBytes == cbRead)
|
|
hr = S_OK;
|
|
else
|
|
hr = S_FALSE;
|
|
}
|
|
else
|
|
{
|
|
hr = E_FAIL;
|
|
}
|
|
}
|
|
|
|
if(pcbRead)
|
|
*pcbRead = cbRead;
|
|
|
|
m_bEOF = (hr != S_OK);
|
|
return hr;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CFileLite::Write
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
HRESULT CFileLite::Write(LPCWSTR pwszText, ULONG* pcbWritten)
|
|
{
|
|
ULONG cbWritten = 0;
|
|
HRESULT hr = S_OK;
|
|
|
|
if(m_hFile && pwszText)
|
|
{
|
|
if(IsUnicode())
|
|
{
|
|
//The file is Unicode, just directly write out the stream of unicode bytes
|
|
hr = WriteBytes((ULONG)(wcslen(pwszText)*sizeof(WCHAR)), (BYTE*)pwszText, &cbWritten);
|
|
}
|
|
else
|
|
{
|
|
//The File is ANSI(MBCS), but the string is Unicode
|
|
//Conversion required...
|
|
static CHAR szBuffer[MAX_QUERY_LEN] = {0};
|
|
ConvertToMBCS(pwszText, szBuffer, MAX_QUERY_LEN);
|
|
|
|
hr = WriteBytes((ULONG)(strlen(szBuffer)*sizeof(CHAR)), (BYTE*)szBuffer, &cbWritten);
|
|
}
|
|
}
|
|
|
|
if(pcbWritten)
|
|
*pcbWritten = cbWritten;
|
|
return hr;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CFileLite::Write
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
HRESULT CFileLite::Write(LPCSTR pszText, ULONG* pcbWritten)
|
|
{
|
|
ULONG cbWritten = 0;
|
|
HRESULT hr = S_OK;
|
|
|
|
if(m_hFile && pszText)
|
|
{
|
|
if(IsUnicode())
|
|
{
|
|
//The file is Unicode, but the string is ANSI
|
|
//Conversion required...
|
|
static WCHAR wszBuffer[MAX_QUERY_LEN] = {0};
|
|
ConvertToWCHAR(pszText, wszBuffer, MAX_QUERY_LEN);
|
|
|
|
hr = WriteBytes((ULONG)(wcslen(wszBuffer)*sizeof(WCHAR)), (BYTE*)wszBuffer, &cbWritten);
|
|
}
|
|
else
|
|
{
|
|
//The File is ANSI(MBCS), just directly write out the stream of bytes
|
|
//to MBCS before writting it directly to the file...
|
|
hr = WriteBytes((ULONG)(strlen(pszText)*sizeof(CHAR)), (BYTE*)pszText, &cbWritten);
|
|
}
|
|
}
|
|
|
|
if(pcbWritten)
|
|
*pcbWritten = cbWritten;
|
|
return hr;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CFileLite::WriteBytes
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
HRESULT CFileLite::WriteBytes(ULONG cBytes, BYTE* rgBytes, ULONG* pcbWritten)
|
|
{
|
|
ULONG cbWritten = 0;
|
|
HRESULT hr = S_OK;
|
|
|
|
if(m_hFile && cBytes)
|
|
{
|
|
ASSERT(rgBytes);
|
|
|
|
//When saving as a Unicode Text file, Notepad always writes out a byte order mark (BOM)
|
|
//Unicode character U+FEFF as the first Unicode character in a file.
|
|
//It uses this character (and not the file extension) to help it distinguish Unicode text
|
|
//from other data.
|
|
if(IsUnicode() && !m_cbWritten)
|
|
{
|
|
//If the file format is Unicode, and we haven't written any bytes to file
|
|
//yet then write out the BOM (Byte Order Mark) to indicate unicode.
|
|
WriteFile(m_hFile, &UNICODE_BYTE_ORDER_MARK, sizeof(UNICODE_BYTE_ORDER_MARK), &m_cbWritten, NULL);
|
|
}
|
|
|
|
//Output to the file
|
|
if(WriteFile(m_hFile, rgBytes, cBytes, &cbWritten, NULL))
|
|
hr = S_OK;
|
|
else
|
|
hr = E_FAIL;
|
|
}
|
|
|
|
if(pcbWritten)
|
|
*pcbWritten = cbWritten;
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CFileLite::WriteFormat
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
HRESULT CFileLite::WriteFormat(LPCWSTR pwszFmt, ...)
|
|
{
|
|
if(!IsOpen())
|
|
return S_OK;
|
|
|
|
va_list marker;
|
|
WCHAR wszBuffer[MAX_QUERY_LEN];
|
|
|
|
// Use format and arguements as input
|
|
//This version will not overwrite the stack, since it only copies
|
|
//upto the max size of the array
|
|
va_start(marker, pwszFmt);
|
|
_vsnwprintf_s(wszBuffer, MAX_QUERY_LEN, _TRUNCATE, pwszFmt, marker);
|
|
va_end(marker);
|
|
|
|
//Make sure there is a NULL Terminator, vsnwprintf will not copy
|
|
//the terminator if length==MAX_QUERY_LEN
|
|
wszBuffer[MAX_QUERY_LEN-1] = wEOL;
|
|
|
|
//Delegate
|
|
return Write(wszBuffer);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CFileLite::Flush
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
HRESULT CFileLite::Flush()
|
|
{
|
|
if(m_hFile)
|
|
{
|
|
// return FlushFileBuffers(m_hFile) ? S_OK : E_FAIL;
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CFileLite::Close
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
HRESULT CFileLite::Close()
|
|
{
|
|
if(m_hFile)
|
|
{
|
|
Flush();
|
|
CloseHandle(m_hFile);
|
|
}
|
|
|
|
m_hFile = NULL;
|
|
m_bEOF = FALSE;
|
|
m_cbWritten = 0;
|
|
m_cbRead = 0;
|
|
return S_OK;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
// LV_InsertColumn
|
|
//
|
|
//////////////////////////////////////////////////////////////////
|
|
INDEX LV_InsertColumn(HWND hWnd, INDEX iColumn, WCHAR* wszName, INT iImage)
|
|
{
|
|
ULONG dwMask = LVCF_TEXT | LVCF_FMT | LVCF_SUBITEM;
|
|
INT dwFmt = LVCFMT_LEFT;
|
|
if(iImage != IMAGE_NONE)
|
|
{
|
|
dwMask |= LVCF_IMAGE;
|
|
dwFmt |= LVCFMT_IMAGE;
|
|
}
|
|
|
|
//LVM_INSERTCOLUMN
|
|
if(IsUnicodeOS())
|
|
{
|
|
//Setup LV_COLUMNINFO
|
|
LV_COLUMNW lvColumnHeader = { dwMask, dwFmt, 0, wszName, 0, 0, iImage, 0};
|
|
return (INDEX)SendMessage(hWnd, LVM_INSERTCOLUMNW, (WPARAM)iColumn, (LPARAM)&lvColumnHeader);
|
|
}
|
|
else
|
|
{
|
|
//Setup LV_COLUMNINFO
|
|
CHAR szBuffer[MAX_NAME_LEN];
|
|
LV_COLUMNA lvColumnHeader = { dwMask, dwFmt, 0, szBuffer, 0, 0, iImage, 0};
|
|
ConvertToMBCS(wszName, szBuffer, MAX_NAME_LEN);
|
|
return (INDEX)SendMessage(hWnd, LVM_INSERTCOLUMNA, (WPARAM)iColumn, (LPARAM)&lvColumnHeader);
|
|
}
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
// LV_InsertItem
|
|
//
|
|
//////////////////////////////////////////////////////////////////
|
|
INDEX LV_InsertItem(HWND hWnd, INDEX iItem, INDEX iSubItem, WCHAR* wszName, LPARAM lParam, INT iImage, UINT iState, UINT iStateMask)
|
|
{
|
|
//Calculate the Mask/flags
|
|
ULONG dwMask = 0;
|
|
if(wszName)
|
|
dwMask |= LVIF_TEXT;
|
|
if(iImage != IMAGE_NONE)
|
|
dwMask |= LVIF_IMAGE;
|
|
if(iState != STATE_NONE)
|
|
dwMask |= LVIF_STATE;
|
|
if(iSubItem == 0)
|
|
dwMask |= LVIF_PARAM;
|
|
|
|
if(IsUnicodeOS())
|
|
{
|
|
//LVM_INSERTITEM
|
|
if(iSubItem==0)
|
|
{
|
|
LV_ITEMW lvItem = { dwMask, (INT)iItem, (INT)iSubItem, iState, iStateMask, wszName, 0, iImage, lParam, 0};
|
|
return (INDEX)SendMessageW(hWnd, LVM_INSERTITEMW, 0, (LPARAM)&lvItem);
|
|
}
|
|
//LVM_SETITEM
|
|
else
|
|
{
|
|
LV_ITEMW lvItem = { dwMask, (INT)iItem, (INT)iSubItem, iState, iStateMask, wszName, 0, iImage, lParam, 0};
|
|
return (INDEX)SendMessageW(hWnd, LVM_SETITEMW, 0, (LPARAM)&lvItem);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
CHAR szBuffer[MAX_QUERY_LEN+1];
|
|
ConvertToMBCS(wszName, szBuffer, MAX_QUERY_LEN);
|
|
|
|
//LVM_INSERTITEM
|
|
if(iSubItem==0)
|
|
{
|
|
LV_ITEMA lvItem = { dwMask, (INT)iItem, (INT)iSubItem, iState, iStateMask, szBuffer, 0, iImage, lParam, 0};
|
|
return (INDEX)SendMessageA(hWnd, LVM_INSERTITEMA, 0, (LPARAM)&lvItem);
|
|
}
|
|
//LVM_SETITEM
|
|
else
|
|
{
|
|
LV_ITEMA lvItem = { dwMask, (INT)iItem, (INT)iSubItem, iState, iStateMask, szBuffer, 0, iImage, lParam, 0};
|
|
return (INDEX)SendMessageA(hWnd, LVM_SETITEMA, 0, (LPARAM)&lvItem);
|
|
}
|
|
}
|
|
|
|
return LVM_ERR;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
// LV_SetItemText
|
|
//
|
|
//////////////////////////////////////////////////////////////////
|
|
BOOL LV_SetItemText(HWND hWnd, INDEX iItem, INDEX iSubItem, WCHAR* pwszName)
|
|
{
|
|
if(IsUnicodeOS())
|
|
{
|
|
//LVM_SETITEM
|
|
LV_ITEMW lvItem = { LVIF_TEXT, (INT)iItem, (INT)iSubItem, 0, 0, pwszName, 0, 0, 0, 0};
|
|
return (BOOL)SendMessage(hWnd, LVM_SETITEMTEXTW, (WPARAM)iItem, (LPARAM)&lvItem);
|
|
}
|
|
else
|
|
{
|
|
CHAR szBuffer[MAX_NAME_LEN+1];
|
|
ConvertToMBCS(pwszName, szBuffer, MAX_NAME_LEN);
|
|
|
|
//LVM_SETITEM
|
|
LV_ITEMA lvItem = { LVIF_TEXT, (INT)iItem, (INT)iSubItem, 0, 0, szBuffer, 0, 0, 0, 0};
|
|
return (BOOL)SendMessageA(hWnd, LVM_SETITEMTEXTA, (WPARAM)iItem, (LPARAM)&lvItem);
|
|
}
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
// LV_SetItemState
|
|
//
|
|
//////////////////////////////////////////////////////////////////
|
|
BOOL LV_SetItemState(HWND hWnd, INDEX iItem, INDEX iSubItem, UINT iState, UINT iStateMask)
|
|
{
|
|
//LVM_SETITEM
|
|
LV_ITEM lvItem = { LVIF_STATE, (INT)iItem, (INT)iSubItem, iState, iStateMask, NULL, 0, 0, 0, 0};
|
|
return (BOOL)SendMessage(hWnd, LVM_SETITEMSTATE, (WPARAM)iItem, (LPARAM)&lvItem);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
// LV_SetItemImage
|
|
//
|
|
//////////////////////////////////////////////////////////////////
|
|
BOOL LV_SetItemImage(HWND hWnd, INDEX iItem, INDEX iSubItem, INT iImage)
|
|
{
|
|
//LVM_SETITEM (With IMAGE mask)
|
|
LV_ITEM lvItem = { LVIF_IMAGE, (INT)iItem, (INT)iSubItem, 0, 0, NULL, 0, iImage, 0, 0};
|
|
return (BOOL)SendMessage(hWnd, LVM_SETITEM, 0, (LPARAM)&lvItem);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
// LV_SetItemParam
|
|
//
|
|
//////////////////////////////////////////////////////////////////
|
|
BOOL LV_SetItemParam(HWND hWnd, INDEX iItem, INDEX iSubItem, LPARAM lParam)
|
|
{
|
|
//LVM_SETITEM (With IMAGE mask)
|
|
LV_ITEM lvItem = { LVIF_PARAM, (INT)iItem, (INT)iSubItem, 0, 0, NULL, 0, 0, lParam, 0};
|
|
return (BOOL)SendMessage(hWnd, LVM_SETITEM, 0, (LPARAM)&lvItem);
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
// LV_GetItemText
|
|
//
|
|
//////////////////////////////////////////////////////////////////
|
|
INDEX LV_GetItemText(HWND hWnd, INDEX iItem, INDEX iSubItem, WCHAR* pwszName, ULONG ulMaxSize)
|
|
{
|
|
ASSERT(pwszName);
|
|
pwszName[0] = wEOL;
|
|
INDEX lReturn = 0;
|
|
|
|
//LVM_GETITEMTEXT
|
|
if(IsUnicodeOS())
|
|
{
|
|
LV_ITEMW lvItem = { LVIF_TEXT, (INT)iItem, (INT)iSubItem, 0, 0, pwszName, ulMaxSize, 0, 0, 0};
|
|
lReturn = (INDEX)SendMessage(hWnd, LVM_GETITEMTEXTW, (WPARAM)iItem, (LPARAM)&lvItem);
|
|
}
|
|
else
|
|
{
|
|
CHAR szBuffer[MAX_NAME_LEN] = {0};
|
|
|
|
LV_ITEMA lvItem = { LVIF_TEXT, (INT)iItem, (INT)iSubItem, 0, 0, szBuffer, MAX_NAME_LEN, 0, 0, 0};
|
|
lReturn = (INDEX)SendMessage(hWnd, LVM_GETITEMTEXTA, (WPARAM)iItem, (LPARAM)&lvItem);
|
|
|
|
ConvertToWCHAR(szBuffer, pwszName, ulMaxSize);
|
|
}
|
|
|
|
return lReturn;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
// LV_GetItemState
|
|
//
|
|
//////////////////////////////////////////////////////////////////
|
|
UINT LV_GetItemState(HWND hWnd, INDEX iItem, UINT iMask)
|
|
{
|
|
//LVM_GETITEMSTATE
|
|
return (UINT)SendMessage(hWnd, LVM_GETITEMSTATE, (WPARAM)iItem, (LPARAM)iMask);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
// LV_GetItemImage
|
|
//
|
|
//////////////////////////////////////////////////////////////////
|
|
INT LV_GetItemImage(HWND hWnd, INDEX iItem, INDEX iSubItem)
|
|
{
|
|
//LVM_GETITEM
|
|
LV_ITEM lvItem = { LVIF_IMAGE, (INT)iItem, (INT)iSubItem, 0, 0, 0, 0, 0, 0, 0};
|
|
SendMessage(hWnd, LVM_GETITEM, 0, (LPARAM)&lvItem);
|
|
return lvItem.iImage;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
// LV_GetItemParam
|
|
//
|
|
//////////////////////////////////////////////////////////////////
|
|
LPARAM LV_GetItemParam(HWND hWnd, INDEX iItem, INDEX iSubItem)
|
|
{
|
|
//LVM_GETITEM
|
|
LV_ITEM lvItem = { LVIF_PARAM, (INT)iItem, (INT)iSubItem, 0, 0, 0, 0, 0, 0, 0};
|
|
SendMessage(hWnd, LVM_GETITEM, 0, (LPARAM)&lvItem);
|
|
return lvItem.lParam;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
// LV_GetSelItems
|
|
//
|
|
//////////////////////////////////////////////////////////////////
|
|
LRESULT LV_GetSelItems(HWND hWnd, INDEX* pcItems, INDEX** prgSelItems, LPARAM** prgSelParams)
|
|
{
|
|
//Get the total Selected Items
|
|
HRESULT hr = S_OK;
|
|
INDEX i,iSelItem =0;
|
|
INDEX cItems = (INDEX)SendMessage(hWnd, LVM_GETSELECTEDCOUNT, 0, 0);
|
|
|
|
//Alloc Output Array
|
|
if(prgSelItems)
|
|
SAFE_ALLOC(*prgSelItems, INDEX, cItems);
|
|
if(prgSelParams)
|
|
SAFE_ALLOC(*prgSelParams, LPARAM, cItems);
|
|
|
|
//Find all params of Selected Items
|
|
iSelItem = (INDEX)SendMessage(hWnd, LVM_GETNEXTITEM, (WPARAM)-1, (LPARAM)LVNI_SELECTED);
|
|
for(i=0; i<cItems; i++)
|
|
{
|
|
if(prgSelItems)
|
|
(*prgSelItems)[i] = iSelItem;
|
|
if(prgSelParams)
|
|
(*prgSelParams)[i] = LV_GetItemParam(hWnd, iSelItem, 0);
|
|
iSelItem = (INDEX)SendMessage(hWnd, LVM_GETNEXTITEM, (WPARAM)iSelItem, (LPARAM)LVNI_SELECTED);
|
|
}
|
|
|
|
CLEANUP:
|
|
if(pcItems)
|
|
*pcItems = cItems;
|
|
return cItems;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
// LV_GetAllItems
|
|
//
|
|
//////////////////////////////////////////////////////////////////
|
|
LRESULT LV_GetAllItems(HWND hWnd, INDEX* pcItems, INDEX** prgItems, LPARAM** prgParams)
|
|
{
|
|
//Get the total Items
|
|
HRESULT hr = S_OK;
|
|
INDEX i=0;
|
|
INDEX cItems = (INDEX)SendMessage(hWnd, LVM_GETITEMCOUNT, 0, 0);
|
|
|
|
//Alloc Output Array
|
|
if(prgItems)
|
|
SAFE_ALLOC(*prgItems, INDEX, cItems);
|
|
if(prgParams)
|
|
SAFE_ALLOC(*prgParams, LPARAM, cItems);
|
|
|
|
//Find all Items
|
|
for(i=0; i<cItems; i++)
|
|
{
|
|
if(prgItems)
|
|
(*prgItems)[i] = i;
|
|
if(prgParams)
|
|
(*prgParams)[i] = LV_GetItemParam(hWnd, i, 0);
|
|
}
|
|
|
|
CLEANUP:
|
|
if(pcItems)
|
|
*pcItems = cItems;
|
|
return cItems;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
// LV_FindItem
|
|
//
|
|
/////////////////////////////////////////////////////////////////
|
|
INDEX LV_FindItem(HWND hWnd, LPARAM lParam, INDEX iStart)
|
|
{
|
|
//LVM_FINDITEM
|
|
LV_FINDINFO lvFindInfo = { LVIF_PARAM, 0, lParam, 0, 0};
|
|
return (INDEX)SendMessage(hWnd, LVM_FINDITEM, (WPARAM)iStart, (LPARAM)&lvFindInfo);
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
// TV_InsertItem
|
|
//
|
|
//////////////////////////////////////////////////////////////////
|
|
HTREEITEM TV_InsertItem(HWND hWnd, HTREEITEM hParent, HTREEITEM hInsAfter, WCHAR* wszName, LPARAM lParam, INT iImage, INT iSelectedImage, UINT iState, UINT iStateMask)
|
|
{
|
|
//Calculate the Mask/flags
|
|
ULONG dwMask = 0;
|
|
if(wszName)
|
|
dwMask |= LVIF_TEXT;
|
|
if(iImage != IMAGE_NONE)
|
|
dwMask |= (LVIF_IMAGE | TVIF_SELECTEDIMAGE);
|
|
if(iState != STATE_NONE)
|
|
dwMask |= LVIF_STATE;
|
|
if(lParam != PARAM_NONE)
|
|
dwMask |= LVIF_PARAM;
|
|
|
|
if(IsUnicodeOS())
|
|
{
|
|
//TVM_INSERTITEM
|
|
TV_INSERTSTRUCTW tvInsertStruct = { hParent, hInsAfter, { dwMask, 0, iState, iStateMask, wszName, 0, iImage, iSelectedImage, 0, lParam} };
|
|
return (HTREEITEM)SendMessageW(hWnd, TVM_INSERTITEMW, 0, (LPARAM)&tvInsertStruct);
|
|
}
|
|
else
|
|
{
|
|
CHAR szBuffer[MAX_NAME_LEN+1];
|
|
ConvertToMBCS(wszName, szBuffer, MAX_NAME_LEN);
|
|
|
|
//TVM_INSERTITEM
|
|
TV_INSERTSTRUCTA tvInsertStruct = { hParent, hInsAfter, { dwMask, 0, iState, iStateMask, szBuffer, 0, iImage, iSelectedImage, 0, lParam} };
|
|
return (HTREEITEM)SendMessageA(hWnd, TVM_INSERTITEMA, 0, (LPARAM)&tvInsertStruct);
|
|
}
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
// TV_GetItemText
|
|
//
|
|
//////////////////////////////////////////////////////////////////
|
|
BOOL TV_GetItemText(HWND hWnd, HTREEITEM hItem, WCHAR* pwszBuffer, LONG ulMaxSize)
|
|
{
|
|
ASSERT(pwszBuffer);
|
|
BOOL bReturn = 0;
|
|
|
|
if(IsUnicodeOS())
|
|
{
|
|
TVITEMW tvItem = { TVIF_TEXT, hItem, 0, 0, pwszBuffer, ulMaxSize, 0, 0, 0, 0};
|
|
bReturn = (BOOL)SendMessage(hWnd, TVM_GETITEMW, 0, (LPARAM)&tvItem);
|
|
}
|
|
else
|
|
{
|
|
CHAR szBuffer[MAX_NAME_LEN] = {0};
|
|
|
|
TVITEMA tvItem = { TVIF_TEXT, hItem, 0, 0, szBuffer, MAX_NAME_LEN, 0, 0, 0, 0};
|
|
bReturn = (BOOL)SendMessage(hWnd, TVM_GETITEMA, 0, (LPARAM)&tvItem);
|
|
|
|
ConvertToWCHAR(szBuffer, pwszBuffer, ulMaxSize);
|
|
}
|
|
|
|
return bReturn;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
// TV_GetItemParam
|
|
//
|
|
//////////////////////////////////////////////////////////////////
|
|
LPARAM TV_GetItemParam(HWND hWnd, HTREEITEM hItem)
|
|
{
|
|
//no-op
|
|
if(hItem == NULL)
|
|
return NULL;
|
|
|
|
TVITEM tvItem = { TVIF_PARAM, hItem, 0, 0, NULL, 0, 0, 0, 0, 0};
|
|
|
|
//GetItem
|
|
SendMessage(hWnd, TVM_GETITEM, 0, (LPARAM)&tvItem);
|
|
|
|
//return the lParam
|
|
return tvItem.lParam;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
// TV_SetItemState
|
|
//
|
|
//////////////////////////////////////////////////////////////////
|
|
BOOL TV_SetItemState(HWND hWnd, HTREEITEM hItem, UINT iState, UINT iStateMask)
|
|
{
|
|
//TVM_SETITEM
|
|
TVITEM tvItem = { TVIF_STATE, hItem, iState, iStateMask, NULL, 0, 0, 0, 0, 0};
|
|
return (BOOL)SendMessage(hWnd, TVM_SETITEM, 0, (LPARAM)&tvItem);
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
// TV_FindItem
|
|
//
|
|
//////////////////////////////////////////////////////////////////
|
|
HTREEITEM TV_FindItem(HWND hWnd, HTREEITEM hParent, WCHAR* wszName)
|
|
{
|
|
ASSERT(hWnd);
|
|
ASSERT(wszName);
|
|
CHAR szBuffer[MAX_NAME_LEN];
|
|
|
|
//Convert to MBCS
|
|
CHAR szName[MAX_NAME_LEN];
|
|
ConvertToMBCS(wszName, szName, MAX_NAME_LEN);
|
|
|
|
TVITEMA tvItemA = { TVIF_TEXT, 0, 0, 0, szBuffer, MAX_NAME_LEN, 0, 0, 0, 0};
|
|
tvItemA.hItem = (HTREEITEM)SendMessage(hWnd, TVM_GETNEXTITEM, (WPARAM)TVGN_CHILD, (LPARAM)hParent);
|
|
while(tvItemA.hItem)
|
|
{
|
|
//Try to find this string in the Tree
|
|
if(SendMessage(hWnd, TVM_GETITEM, 0, (LPARAM)&tvItemA))
|
|
{
|
|
if(strcmp(szName, tvItemA.pszText)==0)
|
|
return tvItemA.hItem;
|
|
}
|
|
|
|
//Otherwise get the NextItem and continue...
|
|
tvItemA.hItem = (HTREEITEM)SendMessage(hWnd, TVM_GETNEXTITEM, (WPARAM)TVGN_NEXT, (LPARAM)tvItemA.hItem);
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CWaitCursor
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
CWaitCursor::CWaitCursor()
|
|
{
|
|
m_hPrevCursor = NULL;
|
|
WaitCursor();
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// ~CWaitCursor
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
CWaitCursor::~CWaitCursor()
|
|
{
|
|
RestoreCursor();
|
|
};
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CWaitCursor::WaitCursor
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
void CWaitCursor::WaitCursor()
|
|
{
|
|
static HCURSOR hWaitCursor = LoadCursor(NULL, IDC_WAIT);
|
|
|
|
//Set the "HourGlass" wait cursor
|
|
m_hPrevCursor = SetCursor(hWaitCursor);
|
|
};
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CWaitCursor::RestoreCursor
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
void CWaitCursor::RestoreCursor()
|
|
{
|
|
//Restore the previous cursor...
|
|
SetCursor(m_hPrevCursor);
|
|
};
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
// DisplayContextMenu
|
|
//
|
|
/////////////////////////////////////////////////////////////////
|
|
BOOL DisplayContextMenu(HWND hWnd, UINT iID, REFPOINTS rPts, HWND hWndParent, BOOL fRelCords)
|
|
{
|
|
//Load the SubMenu
|
|
HMENU hMenu = LoadMenu(GetAppLite()->m_hInstance, MAKEINTRESOURCE(iID));
|
|
HMENU hSubMenu = GetSubMenu(hMenu, 0);
|
|
|
|
RECT rect;
|
|
GetWindowRect(hWnd, &rect);
|
|
POINTS pts = rPts; //Make a copy to modify const...
|
|
|
|
//Coordinates might be Screen Coordinates or Relative
|
|
if(fRelCords)
|
|
{
|
|
rect.top += pts.y;
|
|
rect.bottom += pts.y;
|
|
rect.left += pts.x;
|
|
rect.right += pts.x;
|
|
}
|
|
|
|
//This message may have come from the keyboard
|
|
//Just display at upper left corner
|
|
if(pts.x < rect.left || pts.x > rect.right || pts.y < rect.top || pts.y > rect.bottom)
|
|
{
|
|
pts.x = (SHORT)rect.left + 5;
|
|
pts.y = (SHORT)rect.top + 5;
|
|
}
|
|
|
|
//Display SubMenu
|
|
//Wants (x,y) in Screen Coordinates
|
|
BOOL bResult = TrackPopupMenu(hSubMenu,
|
|
TPM_LEFTALIGN | TPM_RIGHTBUTTON,
|
|
pts.x,
|
|
pts.y,
|
|
0,
|
|
hWndParent,
|
|
NULL);
|
|
|
|
DestroyMenu(hSubMenu);
|
|
DestroyMenu(hMenu);
|
|
return bResult;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
// DisplayDialog
|
|
//
|
|
/////////////////////////////////////////////////////////////////
|
|
LRESULT DisplayDialog(UINT uID, HWND hWndParent, DLGPROC lpDialogFunc, LPARAM lParam)
|
|
{
|
|
//Display DialogBoxParam and dump any errors...
|
|
LRESULT lResult = DialogBoxParam(GetAppLite()->m_hInstance, MAKEINTRESOURCE(uID), hWndParent, lpDialogFunc, lParam);
|
|
GETLASTERROR(lResult != -1);
|
|
|
|
return lResult;
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CDropObject::CDropObject
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
CDropObject::CDropObject()
|
|
{
|
|
//IUnknown
|
|
m_cRef = 0;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CDropObject::~CDropObject
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
CDropObject::~CDropObject()
|
|
{
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// CDropObject::AddRef
|
|
//
|
|
/////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP_(ULONG) CDropObject::AddRef()
|
|
{
|
|
//AddRef
|
|
return ++m_cRef;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// CDropObject::Release
|
|
//
|
|
/////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP_(ULONG) CDropObject::Release()
|
|
{
|
|
//Release
|
|
if(--m_cRef)
|
|
return m_cRef;
|
|
|
|
delete this;
|
|
return 0;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// CDropObject::QueryInterface
|
|
//
|
|
/////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP CDropObject::QueryInterface(REFIID riid, LPVOID *ppv)
|
|
{
|
|
if(!ppv)
|
|
return E_INVALIDARG;
|
|
*ppv = NULL;
|
|
|
|
//IUNKNOWN
|
|
if(riid == IID_IUnknown)
|
|
*ppv = this;
|
|
else if(riid == IID_IDataObject)
|
|
*ppv = (IDataObject*)this;
|
|
|
|
if(*ppv)
|
|
{
|
|
((IUnknown*)(*ppv))->AddRef();
|
|
return S_OK;
|
|
}
|
|
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// CDropObject::GetData
|
|
//
|
|
/////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP CDropObject::GetData(FORMATETC* pformatetcIn, STGMEDIUM* pmedium)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// CDropObject::GetDataHere
|
|
//
|
|
/////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP CDropObject::GetDataHere(FORMATETC* pformatetc, STGMEDIUM* pmedium)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// CDropObject::QueryGetData
|
|
//
|
|
/////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP CDropObject::QueryGetData(FORMATETC* pformatetc)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// CDropObject::GetCanonicalFormatEtc
|
|
//
|
|
/////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP CDropObject::GetCanonicalFormatEtc(FORMATETC* pformatectIn, FORMATETC* pformatetcOut)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// CDropObject::SetData
|
|
//
|
|
/////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP CDropObject::SetData(FORMATETC* pformatetc, STGMEDIUM* pmedium, BOOL fRelease)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// CDropObject::EnumFormatEtc
|
|
//
|
|
/////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP CDropObject::EnumFormatEtc(DWORD dwDirection, IEnumFORMATETC** ppenumFormatEtc)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// CDropObject::DAdvise
|
|
//
|
|
/////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP CDropObject::DAdvise(FORMATETC* pformatetc, DWORD advf, IAdviseSink* pAdvSink, DWORD* pdwConnection)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// CDropObject::DUnadvise
|
|
//
|
|
/////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP CDropObject::DUnadvise(DWORD dwConnection)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// CDropObject::EnumDAdvise
|
|
//
|
|
/////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP CDropObject::EnumDAdvise(IEnumSTATDATA** ppenumAdvise)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CDropSource::CDropSource
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
CDropSource::CDropSource()
|
|
{
|
|
//IUnknown
|
|
m_cRef = 0;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CDropSource::~CDropSource
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
CDropSource::~CDropSource()
|
|
{
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// CDropSource::AddRef
|
|
//
|
|
/////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP_(ULONG) CDropSource::AddRef()
|
|
{
|
|
//AddRef
|
|
return ++m_cRef;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// CDropSource::Release
|
|
//
|
|
/////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP_(ULONG) CDropSource::Release()
|
|
{
|
|
//Release
|
|
if(--m_cRef)
|
|
return m_cRef;
|
|
|
|
delete this;
|
|
return 0;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// CDropSource::QueryInterface
|
|
//
|
|
/////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP CDropSource::QueryInterface(REFIID riid, LPVOID *ppv)
|
|
{
|
|
if(!ppv)
|
|
return E_INVALIDARG;
|
|
*ppv = NULL;
|
|
|
|
//IUNKNOWN
|
|
if(riid == IID_IUnknown)
|
|
*ppv = this;
|
|
else if(riid == IID_IDropSource)
|
|
*ppv = (IDropSource*)this;
|
|
|
|
if(*ppv)
|
|
{
|
|
((IUnknown*)(*ppv))->AddRef();
|
|
return S_OK;
|
|
}
|
|
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// CDropSource::QueryContinueDrag
|
|
//
|
|
/////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP CDropSource::QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// CDropSource::GiveFeedback
|
|
//
|
|
/////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP CDropSource::GiveFeedback(DWORD dwEffect)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CDropTarget::CDropTarget
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
CDropTarget::CDropTarget()
|
|
{
|
|
//IUnknown
|
|
m_cRef = 0;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CDropTarget::~CDropTarget
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
CDropTarget::~CDropTarget()
|
|
{
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// CDropTarget::AddRef
|
|
//
|
|
/////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP_(ULONG) CDropTarget::AddRef()
|
|
{
|
|
//AddRef
|
|
return ++m_cRef;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// CDropTarget::Release
|
|
//
|
|
/////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP_(ULONG) CDropTarget::Release()
|
|
{
|
|
//Release
|
|
if(--m_cRef)
|
|
return m_cRef;
|
|
|
|
delete this;
|
|
return 0;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// CDropTarget::QueryInterface
|
|
//
|
|
/////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP CDropTarget::QueryInterface(REFIID riid, LPVOID *ppv)
|
|
{
|
|
if(!ppv)
|
|
return E_INVALIDARG;
|
|
*ppv = NULL;
|
|
|
|
//IUNKNOWN
|
|
if(riid == IID_IUnknown)
|
|
*ppv = this;
|
|
else if(riid == IID_IDropTarget)
|
|
*ppv = (IDropTarget*)this;
|
|
|
|
if(*ppv)
|
|
{
|
|
((IUnknown*)(*ppv))->AddRef();
|
|
return S_OK;
|
|
}
|
|
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// CDropTarget::DragEnter
|
|
//
|
|
/////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP CDropTarget::DragEnter(IDataObject* pDataObj, DWORD grfKeyState, POINTL pt, DWORD* pdwEffect)
|
|
{
|
|
ASSERT(pDataObj);
|
|
ASSERT(pdwEffect);
|
|
*pdwEffect = DROPEFFECT_COPY;
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// CDropTarget::DragOver
|
|
//
|
|
/////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP CDropTarget::DragOver(DWORD grfKeyState, POINTL pt, DWORD* pdwEffect)
|
|
{
|
|
ASSERT(pdwEffect);
|
|
*pdwEffect = DROPEFFECT_COPY;
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// CDropTarget::DragLeave
|
|
//
|
|
/////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP CDropTarget::DragLeave()
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// CDropTarget::Drop
|
|
//
|
|
/////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP CDropTarget::Drop(IDataObject* pDataObj, DWORD grfKeyState, POINTL pt, DWORD* pdwEffect)
|
|
{
|
|
ASSERT(pdwEffect);
|
|
ASSERT(pDataObj);
|
|
*pdwEffect = DROPEFFECT_COPY;
|
|
HRESULT hr = S_OK;
|
|
|
|
//FORMATC structure
|
|
FORMATETC DataFormat =
|
|
{
|
|
CF_HDROP,
|
|
NULL,
|
|
DVASPECT_CONTENT,
|
|
-1,
|
|
TYMED_HGLOBAL
|
|
};
|
|
|
|
//STGMEDIUM Structure
|
|
STGMEDIUM Medium;
|
|
memset(&Medium, 0, sizeof(STGMEDIUM));
|
|
|
|
//NOTE: If your only dealing with Dragging and Dropping Files
|
|
//you can more simply just use WM_DROPFILES instead of implementing
|
|
//this interface setting everything up, etc...
|
|
|
|
//Obtain the Data...
|
|
if(SUCCEEDED(hr = pDataObj->GetData(&DataFormat, &Medium)))
|
|
{
|
|
HDROP hDrop = (HDROP)Medium.hGlobal;
|
|
|
|
//Obtain the number of files...
|
|
UINT cFiles = DragQueryFile(hDrop, (UINT)-1, NULL, 0);
|
|
|
|
//For every file...
|
|
for(ULONG iFile=0; iFile<cFiles; iFile++)
|
|
{
|
|
CHAR szFileName[_MAX_PATH];
|
|
|
|
DragQueryFile(hDrop, iFile, szFileName, NUMELE(szFileName));
|
|
wMessageBox(GetFocus(), MB_TASKMODAL | MB_ICONERROR | MB_OK,
|
|
wsz_INFO, L"File %d: %S", iFile+1, szFileName);
|
|
}
|
|
}
|
|
|
|
//CLEANUP:
|
|
return hr;
|
|
}
|