reactos/rosapps/devutils/vmingw/winui.cpp
2003-01-07 17:59:20 +00:00

2118 lines
44 KiB
C++

/********************************************************************
* Module: winui.cpp. This is part of WinUI.
*
* Purpose: WinUI main module. Contains procedures relative to User Interface
* and general purpose procedures.
*
* Authors: Manu B.
*
* License: WinUI is covered by GNU General Public License,
* Copyright (C) 2001 Manu B.
* See license.htm for more details.
*
* Revisions:
* Manu B. 11/19/01 OpenDlg & SaveDlg enhancement.
* Manu B. 12/07/01 CIniFile created.
* Manu B. 12/15/01 CWinApp created.
*
********************************************************************/
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <commctrl.h>
#include <ctype.h>
#include "winui.h"
// Callback procedures.
LRESULT CALLBACK MainWndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK ChildWndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK DlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam);
// Declare a CMessageBox instance to use anywhere in the whole app.
CMessageBox MsgBox;
/********************************************************************
* Function: char *StpCpy(char *dest, const char *src).
*
* Purpose: stpcpy clone.
*
* Revisions:
*
********************************************************************/
char *StpCpy(char *dest, const char *src){
while (*src != '\0'){
*dest = *src;
src++;
dest++;
}
return dest;
}
size_t strcpylen(char *dest, const char *src){
char * start = dest;
while (*src != '\0'){
*dest = *src;
dest++;
src++;
}
*dest = '\0';
return (dest-start);
}
/********************************************************************
* Class: CChrono.
*
* Purpose:
*
* Revisions:
*
********************************************************************/
CChrono::CChrono(){
_time = 0;
}
CChrono::~CChrono(){
}
void CChrono::Start(void){
_time = ::GetTickCount();
}
DWORD CChrono::Stop(void){
DWORD diff = ::GetTickCount() - _time;
_time = 0;
return diff;
}
/********************************************************************
* Class: Base Window class.
*
* Purpose:
*
* Revisions:
*
********************************************************************/
CWindow::CWindow(){
_pParent = NULL;
_hInst = 0;
_hWnd = 0;
_lParam = NULL;
}
CWindow::~CWindow(){
}
HWND CWindow::CreateEx(
CWindow * pWindow,
DWORD dwExStyle,
LPCTSTR lpClassName,
LPCTSTR lpWindowName,
DWORD dwStyle,
int x, int y, int nWidth, int nHeight,
HMENU hMenu,
LPVOID lpParam){
// Store a pointer to parent class and to lpParam.
_pParent = pWindow;
_lParam = lpParam;
// Get parent class handles.
HWND hParent;
HINSTANCE hInst;
if(_pParent){
// Have a parent window.
hParent = _pParent->_hWnd;
hInst = _pParent->_hInst;
}else{
// Parent window is desktop.
hParent = 0;
hInst = GetModuleHandle(NULL);
}
_hWnd = CreateWindowEx(
dwExStyle,
lpClassName,
lpWindowName,
dwStyle,
x,
y,
nWidth,
nHeight,
hParent,
(HMENU) hMenu,
hInst,
this); // Retrieve lpParam using this->_lParam.
return _hWnd;
}
HWND CWindow::GetId(void){
return _hWnd;
}
LONG CWindow::SetLong(int nIndex, LONG dwNewLong){
return ::SetWindowLong(_hWnd, nIndex, dwNewLong);
}
LONG CWindow::GetLong(int nIndex){
return ::GetWindowLong(_hWnd, nIndex);
}
LRESULT CWindow::SendMessage(UINT Msg, WPARAM wParam, LPARAM lParam){
return ::SendMessage(_hWnd, Msg, wParam, lParam);
}
bool CWindow::SetPosition(HWND hInsertAfter, int x, int y, int width, int height, UINT uFlags){
return ::SetWindowPos(_hWnd, hInsertAfter, x, y, width, height, uFlags);
}
bool CWindow::Show(int nCmdShow){
return ::ShowWindow(_hWnd, nCmdShow);
}
bool CWindow::Hide(void){
return ::ShowWindow(_hWnd, SW_HIDE);
}
HWND CWindow::SetFocus(void){
return ::SetFocus(_hWnd);
}
/********************************************************************
* Class: CWinBase.
*
* Purpose: Base Application class.
*
* Revisions:
*
********************************************************************/
CWinBase::CWinBase(){
hPrevInst = 0;
lpCmdLine = NULL;
nCmdShow = SW_SHOW;
isWinNT = false;
strcpy( appName, "CWinBase");
}
CWinBase::~CWinBase(){
}
bool CWinBase::Init(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,
int nCmdShow){
_hInst = hInstance;
hPrevInst = hPrevInstance;
lpCmdLine = lpCmdLine;
nCmdShow = nCmdShow;
return true;
}
bool CWinBase::SetName(char * name, char * version){
strcpy(appName, name);
strcat(appName, " ");
if(version)
strcat(appName, version);
return true;
}
bool CWinBase::IsWinNT(void){
OSVERSIONINFO osv = {sizeof(OSVERSIONINFO), 0, 0, 0, 0, ""};
GetVersionEx(&osv);
isWinNT = (osv.dwPlatformId == VER_PLATFORM_WIN32_NT);
return isWinNT;
}
void CWinBase::ParseCmdLine(char * outBuff){
int len = 0;
outBuff[len] = '\0';
LPTSTR cmdLine = GetCommandLine();
while (*cmdLine){
if (*cmdLine == '\"'){
cmdLine++;
while (*cmdLine && *cmdLine != '\"'){
outBuff[len] = *cmdLine;
len++;
cmdLine++;
}
break;
}else{
while (*cmdLine && *cmdLine != ' '){
outBuff[len] = *cmdLine;
len++;
cmdLine++;
}
break;
}
}
outBuff[len] = '\0';
SplitFileName(outBuff, 0);
return;
}
/********************************************************************
* Class: CSDIBase.
*
* Purpose: Base SDI class.
*
* Revisions:
*
********************************************************************/
CSDIBase::CSDIBase(){
mainClass[0] = 0;
hAccel = NULL;
}
CSDIBase::~CSDIBase(){
}
int CSDIBase::Run(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,
int nCmdShow){
Init(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
if (!CustomInit()){
Release();
return 1;
}
MSG Msg;
if (CreateUI()){
while(GetMessage(&Msg, NULL, 0, 0)){
if (!TranslateAccelerator(_hWnd, hAccel, &Msg)){
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
}
}else{
MsgBox.DisplayFatal("CreateUI() failed !");
}
Release();
return Msg.wParam;
}
bool CSDIBase::CustomInit(void){
return true;
}
bool CSDIBase::Release(void){
return true;
}
bool CSDIBase::CreateUI(void){
return false;
}
bool CSDIBase::MainRegisterEx(const char * className){
strcpy(mainClass, className);
// Default values.
wc.cbSize = sizeof(WNDCLASSEX);
wc.lpfnWndProc = MainWndProc;
wc.hInstance = _hInst;
wc.lpszClassName = mainClass;
wc.cbClsExtra = 0;
wc.cbWndExtra = sizeof(CSDIBase *);
return RegisterClassEx(&wc);
}
LRESULT CALLBACK CSDIBase::CMainWndProc(UINT Message, WPARAM wParam, LPARAM lParam){
switch (Message){
case WM_DESTROY:
PostQuitMessage (0);
return 0;
}
return DefWindowProc(_hWnd, Message, wParam, lParam);
}
/********************************************************************
* Callback procedure.
********************************************************************/
LRESULT CALLBACK MainWndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam){
// Get a pointer to the CWindow class that owns this window.
CSDIBase * pSdiBase = (CSDIBase *) (GetWindowLong(hwnd, 0));
if (pSdiBase == 0){ // The pointer isn't set yet.
if (Message == WM_NCCREATE){
// First, get the CSDIBase pointer.
pSdiBase = (CSDIBase *) ((CREATESTRUCT *)lParam)->lpCreateParams;
// Attach pSdiBase and lParam to the window.
SetWindowLong(hwnd, 0, (LONG)(pSdiBase));
SetWindowLong(hwnd, GWL_USERDATA, (LONG) pSdiBase->_lParam);
// Store window handle.
pSdiBase->_hWnd = hwnd;
// Let Windows continue the job.
return pSdiBase->CMainWndProc(Message, wParam, lParam);
}else{
return DefWindowProc(hwnd, Message, wParam, lParam);
}
}
return pSdiBase->CMainWndProc(Message, wParam, lParam);
}
/********************************************************************
* Class: CMDIBase.
*
* Purpose: Base MDI class.
*
* Revisions:
*
********************************************************************/
CMDIBase::CMDIBase(){
}
CMDIBase::~CMDIBase(){
}
bool CMDIBase::ChildRegisterEx(const char * className){
strcpy(MdiClient.childClass, className);
// Default values.
wc.cbSize = sizeof(WNDCLASSEX);
wc.lpfnWndProc = ChildWndProc;
wc.hInstance = _hInst;
wc.lpszClassName = className;
wc.cbClsExtra = 0;
wc.cbWndExtra = 8;//sizeof(CMDIBase *);
return RegisterClassEx(&wc);
}
int CMDIBase::Run(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,
int nCmdShow){
Init(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
if (!CustomInit()){
Release();
return 1;
}
MSG Msg;
if (CreateUI()){
while(GetMessage(&Msg, NULL, 0, 0)){
if (!TranslateAccelerator(_hWnd, hAccel, &Msg)){
if (!TranslateMDISysAccel(MdiClient.GetId(), &Msg)){
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
}
}
}else{
MsgBox.DisplayFatal("CreateUI() failed !");
}
Release();
return Msg.wParam;
}
bool CMDIBase::CustomInit(void){
return true;
}
bool CMDIBase::Release(void){
return true;
}
bool CMDIBase::CreateUI(void){
return false;
}
LRESULT CALLBACK CMDIBase::CMainWndProc(UINT, WPARAM, LPARAM){
return 0;
}
LRESULT CALLBACK CMDIBase::CChildWndProc(CWindow *, UINT, WPARAM, LPARAM){
return 0;
}
/********************************************************************
* Child window callback procedure.
********************************************************************/
LRESULT CALLBACK ChildWndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam){
// Get a pointer to the CWindow class that owns this window.
CMDIChild * pMdiChild = (CMDIChild *) (GetWindowLong(hwnd, 0));
if (pMdiChild == 0){ // The pointer isn't set yet.
if (Message == WM_NCCREATE){
// First, get the CMDIChild pointer.
pMdiChild = (CMDIChild *) ((MDICREATESTRUCT *) ((CREATESTRUCT *)lParam)->lpCreateParams)->lParam;
// Attach pMdiChild and lParam to the window.
//MsgBox.DisplayLong((long) pMdiChild);
SetWindowLong(hwnd, 0, (long)(pMdiChild));
SetWindowLong(hwnd, GWL_USERDATA, (long) pMdiChild->_lParam);
// Store window handle.
pMdiChild->_hWnd = hwnd;
// Attach to a childList so that the list can destroy all MdiChild objects.
((CMDIClient *) pMdiChild->_pParent)->childList.InsertFirst(pMdiChild);
// Let Windows continue the job.
return pMdiChild->_pFrame->CChildWndProc(pMdiChild, Message, wParam, lParam);
}else{
return DefWindowProc(hwnd, Message, wParam, lParam);
}
// Free pMdiChild object.
}else if (Message == WM_NCDESTROY){
((CMDIClient *) pMdiChild->_pParent)->childList.Destroy(pMdiChild);
}
return pMdiChild->_pFrame->CChildWndProc(pMdiChild, Message, wParam, lParam);
}
/********************************************************************
* Class: CMDIClient.
*
* Purpose:
*
* Revisions:
*
********************************************************************/
CMDIClient::CMDIClient(){
initialized = false;
childClass[0] = 0;
}
CMDIClient::~CMDIClient(){
}
void CMDIClient::Init(int menuIndex, UINT idFirstChild){
nPos = menuIndex;
// ID of first created child.
ccs.idFirstChild = idFirstChild;
initialized = true;
}
HWND CMDIClient::CreateEx(CWindow * pWindow, DWORD dwExStyle, DWORD dwStyle, UINT resId){
if (!pWindow || !initialized)
return 0;
// Store a pointer to parent class.
_pParent = pWindow;
// Get parent class handles.
_hInst = _pParent->_hInst;
// Get our "Window menu" handle.
ccs.hWindowMenu = GetSubMenu(GetMenu(_pParent->_hWnd), nPos);
_hWnd = CreateWindowEx(
dwExStyle,
"mdiclient",
NULL,
dwStyle,
0,
0,
100,
100,
_pParent->_hWnd,
(HMENU) resId,
_hInst,
(LPVOID) &ccs);
return _hWnd;
}
LPARAM CMDIClient::GetParam(LPARAM lParam){
MDICREATESTRUCT *mcs = (MDICREATESTRUCT *) ((CREATESTRUCT *) lParam)->lpCreateParams;
return mcs->lParam;
}
/********************************************************************
* Class: CMDIChild.
*
* Purpose: Base Windows Class.
*
* Revisions:
*
********************************************************************/
CMDIChild::CMDIChild(){
_pFrame = NULL;
}
CMDIChild::~CMDIChild(){
}
HWND CMDIChild::CreateEx(CMDIClient * pMdiClient, DWORD dwExStyle, DWORD dwStyle, char * caption, UINT resId, LPVOID lParam){
if (!pMdiClient || !pMdiClient->initialized)
return 0;
// Store pointers, lParam and _hInst.
_pParent = pMdiClient;
_pFrame = (CMDIBase *) pMdiClient->_pParent; // Owner of CChildWndProc.
_lParam = lParam;
_hInst = _pParent->_hInst;
HWND hwnd = CreateWindowEx(
dwExStyle,
pMdiClient->childClass,
caption,
dwStyle,
0,
0,
100,
100,
_pParent->_hWnd,
(HMENU) resId,
_hInst,
this);
return hwnd;
}
/********************************************************************
* Class: CDlgBase.
*
* Purpose:
*
* Revisions:
*
********************************************************************/
CDlgBase::CDlgBase(){
}
CDlgBase::~CDlgBase(){
}
HWND CDlgBase::Create(CWindow * pWindow, WORD wResId, RECT * Pos, LPARAM lParam){
HWND hwnd = 0;
if (pWindow){
hwnd = CreateParam(pWindow, wResId, lParam);
if (Pos)
SetPosition(0, Pos->left, Pos->top, Pos->right, Pos->bottom, 0);
}
return hwnd;
}
int CDlgBase::CreateModal(CWindow * pWindow, WORD wResId, LPARAM lParam){
if (pWindow == NULL)
return 0;
// Don't create a modal dialog if a modeless one already exists.
else if (_hWnd != 0)
return 0;
// Store a pointer to parent class.
_pParent = pWindow;
_lParam = (LPVOID) lParam;
// Get parent class handles.
_hInst = _pParent->_hInst;
return ::DialogBoxParam(_hInst, MAKEINTRESOURCE(wResId), _pParent->_hWnd,
(DLGPROC) DlgProc, (long) this);
}
HWND CDlgBase::CreateParam(CWindow * pWindow, WORD wResId, LPARAM lParam){
if (pWindow == NULL)
return 0;
// Don't create a dialog twice.
else if (_hWnd != 0)
return _hWnd;
// Store a pointer to parent class.
_pParent = pWindow;
_lParam = (LPVOID) lParam;
// Get parent class handles.
_hInst = _pParent->_hInst;
HWND hwnd = CreateDialogParam(_hInst,
MAKEINTRESOURCE(wResId),
_pParent->_hWnd,
(DLGPROC) DlgProc,
(long) this);
return hwnd;
}
BOOL CDlgBase::EndDlg(int nResult){
if (_hWnd){
BOOL result = ::EndDialog(_hWnd, nResult);
_hWnd = 0;
return result;
}
return false;
}
HWND CDlgBase::GetItem(int nIDDlgItem){
return ::GetDlgItem(_hWnd, nIDDlgItem);
}
BOOL CDlgBase::SetItemText(HWND hItem, LPCTSTR lpString){
return ::SendMessage(hItem, WM_SETTEXT, 0, (long)lpString);
}
UINT CDlgBase::GetItemText(HWND hItem, LPTSTR lpString, int nMaxCount){
return ::SendMessage(hItem, WM_GETTEXT, nMaxCount, (long)lpString);
}
LRESULT CALLBACK CDlgBase::CDlgProc(UINT Message, WPARAM, LPARAM){
switch(Message){
case WM_INITDIALOG:
return TRUE;
case WM_CLOSE:
EndDlg(0);
break;
}
return FALSE;
}
/********************************************************************
* Class: CTabbedDlg.
*
* Purpose:
*
* Revisions:
*
********************************************************************/
CTabbedDlg::CTabbedDlg(){
_hWndTab = 0;
Pos.left = 0;
Pos.top = 0;
Pos.right = 100;
Pos.bottom = 100;
}
CTabbedDlg::~CTabbedDlg(){
}
bool CTabbedDlg::SetChildPosition(HWND hChild){
if (!_hWndTab)
return false;
// Get tab's display area.
RECT area;
::GetWindowRect(_hWndTab, &area);
::ScreenToClient(_hWnd, (POINT *) &area.left);
::ScreenToClient(_hWnd, (POINT *) &area.right);
::SendMessage(_hWndTab, TCM_ADJUSTRECT, FALSE, (LPARAM) &area);
::CopyRect(&Pos, &area);
// Get child dialog's rect.
RECT child;
::GetWindowRect(hChild, &child);
::ScreenToClient(_hWnd, (POINT *) &child.left);
::ScreenToClient(_hWnd, (POINT *) &child.right);
// Center child dialog.
int childWidth = child.right-child.left;
int childHeight = child.bottom-child.top;
int hMargin = ((area.right-area.left)-childWidth)/2;
int vMargin = ((area.bottom-area.top)-childHeight)/2;
Pos.left += hMargin;
Pos.top += vMargin;
Pos.right = childWidth;
Pos.bottom = childHeight;
return ::SetWindowPos(hChild, 0, Pos.left, Pos.top, Pos.right, Pos.bottom, 0);
}
void CTabbedDlg::OnNotify(int, LPNMHDR notify){
// Dispatch tab control messages.
switch (notify->code){
case TCN_SELCHANGING:
OnSelChanging(notify);
break;
case TCN_SELCHANGE:
OnSelChange(notify);
break;
}
}
void CTabbedDlg::OnSelChanging(LPNMHDR notify){
// Hide child dialog that is deselected.
if (notify->hwndFrom == _hWndTab){
CWindow * pPaneDlg = (CWindow *) GetParam();
if (pPaneDlg){
if (pPaneDlg->_hWnd)
pPaneDlg->Hide();
}
}
}
void CTabbedDlg::OnSelChange(LPNMHDR notify){
// Show child dialog that is selected.
if (notify->hwndFrom == _hWndTab){
CWindow * pPaneDlg = (CWindow *) GetParam();
if (pPaneDlg){
if (pPaneDlg->_hWnd)
pPaneDlg->Show();
pPaneDlg->SetFocus();
}
}
}
LPARAM CTabbedDlg::GetParam(void){
if (!_hWndTab)
return false;
int iItem = ::SendMessage(_hWndTab, TCM_GETCURSEL, 0, 0);
tcitem.mask = TCIF_PARAM;
BOOL result = ::SendMessage(_hWndTab, TCM_GETITEM, iItem, (long) &tcitem);
if (result)
return tcitem.lParam;
return 0;
}
/********************************************************************
* Callback procedure.
********************************************************************/
LRESULT CALLBACK DlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam){
// Get a pointer to the CWindow class that owns this window.
CDlgBase * pDlgBase = (CDlgBase *) (GetWindowLong(hwnd, DWL_USER));
if (pDlgBase == 0){ // The pointer isn't set yet.
if (Message == WM_INITDIALOG){
// First, get the CDlgBase pointer.
pDlgBase = (CDlgBase *) lParam;
// Attach pDlgBase and lParam to the window.
SetWindowLong(hwnd, DWL_USER, (LONG) pDlgBase);
SetWindowLong(hwnd, GWL_USERDATA, (LONG) pDlgBase->_lParam);
// Store window handle.
pDlgBase->_hWnd = hwnd;
// Let Windows continue the job.
return pDlgBase->CDlgProc(Message, wParam, (LONG) pDlgBase->_lParam);
}else{
return FALSE;
}
}
return pDlgBase->CDlgProc(Message, wParam, lParam);
}
/********************************************************************
* Class: CToolBar.
*
* Purpose:
*
* Revisions:
*
********************************************************************/
CToolBar::CToolBar(){
}
CToolBar::~CToolBar(){
}
HWND CToolBar::CreateEx(CWindow * pWindow, DWORD dwExStyle, DWORD dwStyle, UINT resId){
if (!pWindow)
return 0;
// Store a pointer to parent class.
_pParent = pWindow;
// Get parent class handles.
_hInst = _pParent->_hInst;
_hWnd = CreateWindowEx(
dwExStyle,
TOOLBARCLASSNAME,
NULL,
dwStyle,
0,
0,
100,
100,
_pParent->_hWnd,
(HMENU) resId,
_hInst,
NULL);
if(_hWnd)
// For backward compatibility.
::SendMessage(_hWnd, TB_BUTTONSTRUCTSIZE, (WPARAM) sizeof(TBBUTTON), 0);
return _hWnd;
}
LRESULT CToolBar::AddBitmap(UINT resId, int nBmp, HINSTANCE hInstance){
if (!_hWnd)
return -1;
// Add the bitmap containing button images to the toolbar.
TBADDBITMAP tbab;
if (hInstance == HINST_COMMCTRL)
tbab.hInst = hInstance;
else
tbab.hInst = _hInst;
tbab.nID = resId;
return ::SendMessage(_hWnd, TB_ADDBITMAP, (WPARAM) nBmp, (WPARAM) &tbab);
}
BOOL CToolBar::AddButtons(TBBUTTON * tbButtons, UINT numButtons){
if (!_hWnd)
return FALSE;
// Add the buttons to the toolbar.
return ::SendMessage(_hWnd, TB_ADDBUTTONS, (WPARAM) numButtons, (LPARAM) tbButtons);
}
/********************************************************************
* Class: CStatusBar.
*
* Purpose:
*
* Revisions:
*
********************************************************************/
CStatusBar::CStatusBar(){
numParts = 0;
}
CStatusBar::~CStatusBar(){
}
HWND CStatusBar::CreateEx(CWindow * pWindow, DWORD dwExStyle, DWORD dwStyle, UINT resId){
if (!pWindow)
return 0;
// Store a pointer to parent class.
_pParent = pWindow;
// Get parent class handles.
_hInst = _pParent->_hInst;
_hWnd = CreateWindowEx(
dwExStyle,
STATUSCLASSNAME,
NULL,
dwStyle,
0,
0,
100,
100,
_pParent->_hWnd,
(HMENU) resId,
_hInst,
NULL);
return _hWnd;
}
void CStatusBar::SetParts(int nParts, int * aWidths){
numParts = nParts;
::SendMessage(_hWnd, SB_SETPARTS, nParts, (LPARAM) aWidths);
}
void CStatusBar::WriteString(char * string, int part){
if (part <= numParts)
::SendMessage(_hWnd, SB_SETTEXT, part, (LPARAM) string);
}
void CStatusBar::WriteLong(long number, int part){
char longbuf[10];
itoa (number, longbuf, 10);
WriteString(longbuf, part);
}
/********************************************************************
* Class: CTabCtrl.
*
* Purpose: Tab control.
*
* Revisions:
*
********************************************************************/
CTabCtrl::CTabCtrl(){
}
CTabCtrl::~CTabCtrl(){
}
HWND CTabCtrl::CreateEx(CWindow * pWindow, DWORD dwExStyle, DWORD dwStyle, UINT resId, LPVOID lpParam){
if (!pWindow)
return 0;
// TODO also use lpParam for each control ?
// Store a pointer to parent class and to lpParam.
_pParent = pWindow;
_lParam = lpParam;
// Get parent class handles.
_hInst = _pParent->_hInst;
_hWnd = CreateWindowEx(
dwExStyle,
WC_TABCONTROL,
NULL,
dwStyle,
0,
0,
100,
100,
_pParent->_hWnd,
(HMENU) resId,
_hInst,
lpParam);
return _hWnd;
}
int CTabCtrl::InsertItem(int iItem, UINT mask, DWORD dwState, DWORD dwStateMask,
LPTSTR pszText, int cchTextMax, int iImage, LPARAM lParam){
tcitem.mask = mask;
#if (_WIN32_IE >= 0x0300)
tcitem.dwState = dwState;
tcitem.dwStateMask = dwStateMask;
#else
tcitem.lpReserved1 = 0;
tcitem.lpReserved2 = 0;
#endif
tcitem.pszText = pszText;
tcitem.cchTextMax = cchTextMax;
tcitem.iImage = iImage;
tcitem.lParam = lParam;
return ::SendMessage(_hWnd, TCM_INSERTITEM, iItem, (long) &tcitem);
}
BOOL CTabCtrl::SetItem_Param(int iItem, LPARAM lParam){
tcitem.mask = TCIF_PARAM;
tcitem.lParam = lParam;
return ::SendMessage(_hWnd, TCM_SETITEM, iItem, (long) &tcitem);
}
int CTabCtrl::GetCurSel(void){
return ::SendMessage(_hWnd, TCM_GETCURSEL, 0, 0);
}
LPARAM CTabCtrl::GetItem_Param(int iItem){
tcitem.mask = TCIF_PARAM;
BOOL result = ::SendMessage(_hWnd, TCM_GETITEM, iItem, (long) &tcitem);
if (result)
return tcitem.lParam;
return 0;
}
/********************************************************************
* Class: CTreeView.
*
* Purpose:
*
* Revisions:
*
********************************************************************/
CTreeView::CTreeView(){
}
CTreeView::~CTreeView(){
}
HWND CTreeView::CreateEx(CWindow * pWindow, DWORD dwExStyle, DWORD dwStyle, UINT resId, LPVOID lpParam){
if (!pWindow)
return 0;
// Store a pointer to parent class.
_pParent = pWindow;
// Get parent class handles.
_hInst = _pParent->_hInst;
_hWnd = CreateWindowEx(
dwExStyle,
WC_TREEVIEW,
NULL,
dwStyle,
0,
0,
100,
100,
_pParent->_hWnd,
(HMENU) resId,
_hInst,
lpParam);
return _hWnd;
}
HTREEITEM CTreeView::CreateItem(HTREEITEM hParent, HTREEITEM hInsertAfter, int iImage, LPTSTR pszText, LPARAM lParam){
tvi.hParent = hParent;
tvi.hInsertAfter = hInsertAfter;
tvi.item.mask = TVIF_STATE | TVIF_TEXT | TVIF_IMAGE
| TVIF_SELECTEDIMAGE | TVIF_PARAM ;
tvi.item.stateMask = TVIS_EXPANDED;
tvi.item.state = TVIS_EXPANDED;
tvi.item.pszText = pszText;
tvi.item.iImage = iImage;
tvi.item.iSelectedImage = iImage;
tvi.item.lParam = (LPARAM) lParam;
return (HTREEITEM) ::SendMessage(_hWnd, TVM_INSERTITEM, 0, (LPARAM)&tvi);
}
LPARAM CTreeView::GetSelectedItemParam(void){
_TvItem.hItem = TreeView_GetSelection(_hWnd);
_TvItem.mask = TVIF_PARAM;
_TvItem.lParam = 0;
TreeView_GetItem(_hWnd, (long) &_TvItem);
return _TvItem.lParam;
}
/********************************************************************
* Class: CListView.
*
* Purpose:
*
* Revisions:
*
********************************************************************/
CListView::CListView(){
lastRow = 0;
}
CListView::~CListView(){
}
HWND CListView::CreateEx(CWindow * pWindow, DWORD dwExStyle, DWORD dwStyle, UINT resId){
if (!pWindow)
return 0;
// Store a pointer to parent class.
_pParent = pWindow;
// Get parent class handles.
_hInst = _pParent->_hInst;
_hWnd = CreateWindowEx(
dwExStyle,
WC_LISTVIEW,
NULL,
dwStyle,
0,
0,
100,
100,
_pParent->_hWnd,
(HMENU) resId,
_hInst,
NULL);
return _hWnd;
}
void CListView::Clear(void){
// Win9x ListView clear is too slow.
int numitems = ::SendMessage(_hWnd, LVM_GETITEMCOUNT, 0, 0);
for (int n = 0; n < numitems; n++){
::SendMessage(_hWnd, LVM_DELETEITEM, (WPARAM) 0, 0);
}
lastRow = 0;
}
/********************************************************************
* Class: CScintilla.
*
* Purpose:
*
* Revisions:
*
********************************************************************/
CScintilla::CScintilla(){
}
CScintilla::~CScintilla(){
}
HWND CScintilla::CreateEx(CWindow * pWindow, DWORD dwExStyle, DWORD dwStyle, UINT resId, LPVOID lpParam){
if (!pWindow)
return 0;
// Store a pointer to parent class.
_pParent = pWindow;
// Get parent class handles.
_hInst = _pParent->_hInst;
_hWnd = CreateWindowEx(
dwExStyle,
"Scintilla",
NULL,
dwStyle,
0,
0,
100,
100,
_pParent->_hWnd,
(HMENU) resId,
_hInst,
lpParam);
return _hWnd;
}
/********************************************************************
* Class: CSplitter.
*
* Purpose:
*
* Revisions:
*
********************************************************************/
CSplitter::CSplitter(){
Pane1 = NULL;
Pane2 = NULL;
size = 4;
p = 0;
isActive = false;
initialized = false;
}
CSplitter::~CSplitter(){
}
void CSplitter::Init(CWindow * pane1, CWindow * pane2, bool vertical,
int barPos, int barMode){
Pane1 = pane1;
Pane2 = pane2;
if(Pane1 && Pane2)
initialized = true;
isVertical = vertical;
p = barPos;
mode = barMode;
}
bool CSplitter::Show(int){
return false;
}
bool CSplitter::Hide(void){
return false;
}
bool CSplitter::SetPosition(HWND, int x, int y, int width, int height, UINT){
pos.left = x;
pos.top = y;
pos.right = width;
pos.bottom = height;
if(isVertical)
SetVertPosition();
else
SetHorzPosition();
return true;
}
void CSplitter::SetVertPosition(void){
psize = p+size;
barPos.left = pos.left+p;
barPos.top = pos.top;
barPos.right = size;
barPos.bottom = pos.bottom;
Pane1->SetPosition(0,
pos.left,
pos.top,
p,
pos.bottom,
0);
Pane2->SetPosition(0,
pos.left +psize,
pos.top,
pos.right -psize,
pos.bottom,
0);
}
void CSplitter::SetHorzPosition(void){
psize = p+size;
barPos.left = pos.left;
barPos.top = pos.top+pos.bottom-psize;
barPos.right = pos.right;
barPos.bottom = size;
Pane1->SetPosition(0,
pos.left,
pos.top,
pos.right,
pos.bottom -psize,
0);
Pane2->SetPosition(0,
pos.left,
pos.top +pos.bottom-p,
pos.right,
p,
0);
}
bool CSplitter::HaveMouse(HWND hwnd, short, short){
POINT ptCursor;
::GetCursorPos(&ptCursor);
POINT ptClient = ptCursor;
::ScreenToClient(hwnd, &ptClient);
if ( ptClient.x >= barPos.left
&& ptClient.x <= barPos.left+barPos.right
&& ptClient.y >= barPos.top
&& ptClient.y <= barPos.top+barPos.bottom){
return true;
}
return false;
}
bool CSplitter::OnSetCursor(HWND hwnd, LPARAM){
if(HaveMouse(hwnd, 0, 0)){
if (isVertical){
::SetCursor(::LoadCursor(NULL, IDC_SIZEWE));
return true;
}else{
::SetCursor(::LoadCursor(NULL, IDC_SIZENS));
return true;
}
}
return false;
}
bool CSplitter::OnLButtonDown(HWND hwnd, short xPos, short yPos){
if (HaveMouse(hwnd, 0, 0)){
// Begin of mouse capture.
isActive = true;
::SetCapture(hwnd);
// Save initial mouse position.
initialPos.x = xPos;
initialPos.y = yPos;
// Converts bar position for Xor bar.
POINT xorPos;
RECT rect;
xorPos.x = barPos.left;
xorPos.y = barPos.top;
ClientToWindow(hwnd, &xorPos, &rect);
// Draw the Xor bar.
HDC hdc;
hdc = GetWindowDC(hwnd);
DrawXorBar(hdc, xorPos.x, xorPos.y, barPos.right, barPos.bottom);
// Save initial position for future erasing.
initialXorPos.x = xorPos.x;
initialXorPos.y = xorPos.y;
ReleaseDC(hwnd, hdc);
}
return isActive;
}
void CSplitter::OnLButtonUp(HWND hwnd, short xPos, short yPos){
if (isActive) {
// Erase the Xor bar *********************
HDC hdc;
hdc = GetWindowDC(hwnd);
DrawXorBar(hdc, initialXorPos.x, initialXorPos.y, barPos.right, barPos.bottom);
ReleaseDC(hwnd, hdc);
// Move Splitter to new position *******************
newPos.x = xPos;
newPos.y = yPos;
if(isVertical)
deltaPos = newPos.x - initialPos.x;
else
deltaPos = newPos.y - initialPos.y;/**/
if (deltaPos != 0)
Move(barPos.left + deltaPos, barPos.top + deltaPos);
// End of capture.
::ReleaseCapture();
isActive = false;
}
}
void CSplitter::OnMouseMove(HWND hwnd, short xPos, short yPos){
if (isActive) {
newPos.x = xPos;
newPos.y = yPos;
// Draw the Xor bar *********************
POINT xorPos;
RECT rect;
if(isVertical){
deltaPos = newPos.x - initialPos.x;
xorPos.x = barPos.left + deltaPos;
xorPos.y = barPos.top;
// Convert coordinates.
ClientToWindow(hwnd, &xorPos, &rect);
// Convert rect.
OffsetRect(&rect, -rect.left, -rect.top);
if(xorPos.x < 20)
xorPos.x = 20;
if(xorPos.x > rect.right-24)
xorPos.x = rect.right-24;
}else{
deltaPos = newPos.y - initialPos.y;
xorPos.x = barPos.left;
xorPos.y = barPos.top + deltaPos;
// Convert coordinates.
ClientToWindow(hwnd, &xorPos, &rect);
// Convert rect.
OffsetRect(&rect, -rect.left, -rect.top);
if(xorPos.y < 20)
xorPos.y = 20;
if(xorPos.y > rect.bottom-24)
xorPos.y = rect.bottom-24;
}
HDC hdc;
hdc = GetWindowDC(hwnd);
DrawXorBar(hdc, initialXorPos.x, initialXorPos.y, barPos.right, barPos.bottom);
DrawXorBar(hdc, xorPos.x, xorPos.y, barPos.right, barPos.bottom);
initialXorPos.x = xorPos.x;
initialXorPos.y = xorPos.y;
ReleaseDC(hwnd, hdc);
}
}
void CSplitter::Move(int mouseX, int mouseY){
if(isVertical){
p = mouseX;
SetVertPosition();
}else{
p = pos.bottom - size - mouseY+pos.top;
SetHorzPosition();
}
}
void CSplitter::ClientToWindow(HWND hwnd, POINT * pt, RECT * rect){
// Bar position.
ClientToScreen(hwnd, pt);
// Window rect.
GetWindowRect(hwnd, rect);
// Convert the bar coordinates relative to the top-left of the window.
pt->x -= rect->left;
pt->y -= rect->top;
}
void CSplitter::DrawXorBar(HDC hdc, int x1, int y1, int width, int height){
static WORD _dotPatternBmp[8] =
{
0x00aa, 0x0055, 0x00aa, 0x0055,
0x00aa, 0x0055, 0x00aa, 0x0055
};
HBITMAP hbm;
HBRUSH hbr, hbrushOld;
hbm = CreateBitmap(8, 8, 1, 1, _dotPatternBmp);
hbr = CreatePatternBrush(hbm);
SetBrushOrgEx(hdc, x1, y1, 0);
hbrushOld = (HBRUSH)SelectObject(hdc, hbr);
PatBlt(hdc, x1, y1, width, height, PATINVERT);
SelectObject(hdc, hbrushOld);
DeleteObject(hbr);
DeleteObject(hbm);
}
/********************************************************************
* Class: CBitmap.
*
* Purpose:
*
* Revisions:
*
********************************************************************/
CBitmap::CBitmap(){
hBitmap = NULL;
}
CBitmap::~CBitmap(){
if (hBitmap)
DeleteObject(hBitmap);
}
HBITMAP CBitmap::Load(CWindow * pWindow, LPCTSTR lpBitmapName){
if (!hBitmap) // Don't create twice.
hBitmap = ::LoadBitmap(pWindow->_hInst, lpBitmapName);
return hBitmap;
}
HBITMAP CBitmap::Load(CWindow * pWindow, WORD wResId){
if (!hBitmap) //Don't create twice.
hBitmap = ::LoadBitmap(pWindow->_hInst, MAKEINTRESOURCE(wResId));
return hBitmap;
}
BOOL CBitmap::Destroy(void){
BOOL result = false;
if (hBitmap)
result = DeleteObject(hBitmap);
return result;
}
/********************************************************************
* Class: CImageList.
*
* Purpose:
*
* Revisions:
*
********************************************************************/
CImageList::CImageList(){
hImgList = NULL;
}
CImageList::~CImageList(){
if (hImgList)
ImageList_Destroy(hImgList);
}
HIMAGELIST CImageList::Create(int cx, int cy, UINT flags, int cInitial, int cGrow){
if (!hImgList) // Don't create twice.
hImgList = ::ImageList_Create(cx, cy, flags, cInitial, cGrow);
return hImgList;
}
int CImageList::AddMasked(CBitmap * pBitmap, COLORREF crMask){
return ImageList_AddMasked(hImgList, pBitmap->hBitmap, crMask);
}
/********************************************************************
* Class: CMessageBox.
*
* Purpose:
*
* Revisions:
*
********************************************************************/
CMessageBox::CMessageBox(){
hParent = 0;
strcpy(caption, "CMessageBox");
}
CMessageBox::~CMessageBox(){
}
void CMessageBox::SetParent(HWND hwnd){
hParent = hwnd;
}
void CMessageBox::SetCaption(char * string){
strcpy(caption, string);
}
void CMessageBox::DisplayString(char * string, char * substring, UINT uType){
if(!substring){
MessageBox (hParent, string, caption, uType);
}else{
sprintf(msgBuf, string, substring);
MessageBox (hParent, msgBuf, caption, uType);
}
}
void CMessageBox::DisplayFatal(char * string, char * substring){
DisplayString(string, substring, MB_OK | MB_ICONERROR);
}
void CMessageBox::DisplayWarning(char * string, char * substring){
DisplayString(string, substring, MB_OK | MB_ICONWARNING);
}
void CMessageBox::DisplayLong(long number){
char longbuf[10];
itoa (number, longbuf, 10);
DisplayString(longbuf);
}
void CMessageBox::DisplayRect(RECT * rect){
if (!rect)
return;
sprintf(msgBuf, "left: %ld top: %ld right: %ld bottom: %ld", rect->left, rect->top, rect->right, rect->bottom);
MessageBox (hParent, msgBuf, caption, MB_OK);
}
int CMessageBox::Ask(char * question, bool canCancel){
if (canCancel){
// Cancel button.
return MessageBox(hParent, question, caption, MB_YESNOCANCEL | MB_ICONWARNING);
}else{
// No cancel.
return MessageBox(hParent, question, caption, MB_YESNO | MB_ICONWARNING);
}
}
int CMessageBox::AskToSave(bool canCancel){
char question[] = "Save changes ?";
if (canCancel){
// Cancel button.
return Ask(question, true);
}else{
// No cancel.
return Ask(question, false);
}
}
/********************************************************************
* Class: CFileDlgBase.
*
* Purpose: Open/Save Dlg.
*
* Revisions:
*
********************************************************************/
CFileDlgBase::CFileDlgBase(){
ofn.lStructSize = sizeof(OPENFILENAME); // DWORD
Reset();
}
CFileDlgBase::~CFileDlgBase(){
}
void CFileDlgBase::Reset(void){
// Set methods.
ofn.lpstrTitle = 0; // LPCTSTR
ofn.nFilterIndex = 0; // DWORD
ofn.lpstrFilter = 0; // LPCTSTR
ofn.lpstrDefExt = 0; // LPCTSTR
ofn.Flags = 0; // DWORD
ofn.lpstrInitialDir = 0; // LPCTSTR
// Get methods.
nNextFileOffset = 0;
ofn.nFileOffset = 0; // WORD
ofn.nFileExtension = 0; // WORD
// Unused.
ofn.hInstance = 0; // HINSTANCE
ofn.lpstrCustomFilter = 0; // LPTSTR
ofn.nMaxCustFilter = 0; // DWORD
ofn.lpstrFileTitle = 0; // LPTSTR
ofn.nMaxFileTitle = 0; // DWORD
ofn.lCustData = 0; // DWORD
ofn.lpfnHook = 0; // LPOFNHOOKPROC
ofn.lpTemplateName = 0; // LPCTSTR
}
void CFileDlgBase::SetData(char * filter, char * defExt, DWORD flags){
SetFilter(filter);
SetDefExt(defExt);
SetFlags(flags);
}
void CFileDlgBase::SetTitle(char * title){
ofn.lpstrTitle = title;
}
void CFileDlgBase::SetFilterIndex(DWORD filterIndex){
ofn.nFilterIndex = filterIndex;
}
void CFileDlgBase::SetFilter(char * filter){
ofn.lpstrFilter = filter;
}
void CFileDlgBase::SetDefExt(char * defExt){
ofn.lpstrDefExt = defExt;
}
void CFileDlgBase::SetFlags(DWORD flags){
ofn.Flags = flags;
}
void CFileDlgBase::SetInitialDir(char * lpstrInitialDir){
ofn.lpstrInitialDir = lpstrInitialDir;
}
WORD CFileDlgBase::GetFileOffset(void){
return ofn.nFileOffset;
}
WORD CFileDlgBase::GetFileExtension(void){
return ofn.nFileExtension;
}
WORD CFileDlgBase::GetNextFileOffset(void){
// Analyses a "path\0file1\0file2\0file[...]\0\0" string returned by Open/SaveDlg.
char * srcFiles = ofn.lpstrFile;
if (srcFiles){
if ((ofn.Flags & OFN_ALLOWMULTISELECT) == OFN_ALLOWMULTISELECT){
// Initialize first call.
if (!nNextFileOffset)
nNextFileOffset = ofn.nFileOffset;
// Parse the string.
while (srcFiles[nNextFileOffset] != '\0')
nNextFileOffset++;
// Get next char.
nNextFileOffset++;
// End of string ?
if (srcFiles[nNextFileOffset] == '\0')
nNextFileOffset = 0;
return nNextFileOffset;
}
}
return 0;
}
bool CFileDlgBase::OpenFileName(CWindow * pWindow, char * pszFileName, DWORD nMaxFile){
if (!pWindow)
return false;
ofn.hwndOwner = pWindow->_hWnd; // HWND
ofn.lpstrFile = pszFileName; // LPTSTR
ofn.nMaxFile = nMaxFile; // DWORD
return ::GetOpenFileName(&ofn);
}
bool CFileDlgBase::SaveFileName(CWindow * pWindow, char * pszFileName, DWORD nMaxFile){
if (!pWindow)
return false;
pszFileName[0] = '\0';
ofn.hwndOwner = pWindow->_hWnd; // HWND
ofn.lpstrFile = pszFileName; // LPTSTR
ofn.nMaxFile = nMaxFile; // DWORD
return ::GetSaveFileName(&ofn);
}
/********************************************************************
* Class: CPath.
*
* Purpose:
*
* Revisions:
*
********************************************************************/
CPath::CPath(){
}
CPath::~CPath(){
}
bool CPath::ChangeDirectory(char * dir){
return SetCurrentDirectory(dir);
}
/********************************************************************
* Paths.
********************************************************************/
void SplitFileName(char * dirName, char * fileName){
int n;
int len = strlen (dirName);
for (n = len; n > 2; n--){
if (dirName[n] == '\\' ){
if (fileName)
strcpy (fileName, &dirName[n+1]);
dirName[n+1] = 0;
break;
}
}
}
bool ChangeFileExt(char * fileName, char * ext){
int len = strlen(fileName);
for (int n=len; n > 0; n--){
if (fileName[n] == '.'){
fileName[n+1] = 0;
strcat(fileName, ext);
return true;
}
}
return false; // No file extension.
}
/********************************************************************
* Class: CIniFile.
*
* Purpose: "GetPrivateProfileString()" like procedure.
*
* Revisions:
*
********************************************************************/
CIniFile::CIniFile(){
buffer = NULL;
pcurrent = NULL;
psection = NULL;
}
CIniFile::~CIniFile(){
Close();
}
void CIniFile::Close(void){
if (buffer)
free(buffer);
buffer = NULL;
pcurrent = NULL;
psection = NULL;
}
bool CIniFile::Load(char * fullPath){
if (buffer)
Close();
FILE * file;
/* FIXME: ZeroMemory because open/close projects can cause
GetString to found data from previous projects. */
// ZeroMemory(buffer, MAX_BLOC_SIZE);
file = fopen(fullPath, "rb");
if (file){
buffer = (char *) malloc(MAX_BLOC_SIZE);
if (!buffer)
return false;
fread(buffer, 1, MAX_BLOC_SIZE, file);
if (0 != fread(buffer, 1, sizeof(buffer), file)){
MsgBox.DisplayString("CIniFile ERROR: OVERFOW");
fclose(file);
Close();
return false;
}
fclose(file);
// Initialize current pointer.
pcurrent = buffer;
return true;
}
return false;
}
int CIniFile::GetInt(char * key, char * section){
char integer[32];
if (GetString(integer, key, section)){
return atoi(integer);
}
return 0;
}
//******************************************************
// Reminder :
// GetPrivateProfileString("Section", "Key", "default_string", data, size, iniFilePath);
//******************************************************
bool CIniFile::GetString(char * data, char * key, char * section){
/* Copies data and returns true if successfull */
char *pstop;
if (section){
/* Parse from pcurrent until the end of buffer */
pstop = pcurrent;
for ( ; ; ){
if (*pcurrent == '\0'){
/* Parse again from beginning to pstop */
pcurrent = buffer;
for ( ; ; ){
if (FindSection(pcurrent, section))
break; // Found !
if (pcurrent >= pstop)
return false; // Not found !
}
}
if (FindSection(pcurrent, section))
break; // Found !
}
}
if (psection){
/* Section Found */
pstop = pcurrent;
//MsgBox.DisplayString(pcurrent);
for ( ; ; ){
if (*pcurrent == '\0' || *pcurrent == '['){
/* Parse again from beginning to pstop */
pcurrent = psection;
for ( ; ; ){
if (FindData(pcurrent, key, data))
break; // Found !
if (pcurrent >= pstop)
return false; // Not found !
}
}
if (FindData(pcurrent, key, data))
break; // Found !
}
}
//MsgBox.DisplayString(pcurrent);
return true;
}
bool CIniFile::FindSection(char * s, char * section){
/* Search the section through one line of text */
/* Returns true if successful, false otherwise */
/* This procedure increments current pointer to the end of line */
if (!section)
return false;
bool sectionFound = false;
psection = NULL;
/* Skip spaces and comments */
s = SkipUnwanted(s);
/* End of buffer ? */
if (*s == '\0'){
pcurrent = s;
return false;
/* A section ? */
}else if (*s == '['){
s++;
if (*s == '\0'){
pcurrent = s;
return false;
}
/* Parse the section name */
int len = strlen(section);
if (!strncmp(s, section, len)){
s+=len;
if (*s == ']'){
/* Section found ! */
sectionFound = true;
}
}
}
/* Increment current pointer until the end of current line */
while (*s != '\0' && *s != '\n')
s++;
pcurrent = s;
if (sectionFound)
psection = pcurrent;
return sectionFound;
}
bool CIniFile::FindData(char * s, char * key, char * data){
/* Search the key through one line of text */
/* Returns true if successful, false otherwise */
/* This procedure increments current pointer to the end of line */
bool keyFound = false;
/* Skip spaces and comments */
s = SkipUnwanted(s);
/* End of buffer ? End of section ? */
if (*s == '\0' || *s == '['){
pcurrent = s;
return false;
/* Search the key */
}else{
int len = strlen(key);
/* Compare key and s */
if (!strncmp(s, key, len)){
s+=len;
/* Search an '=' sign */
while (isspace(*s)){
if (*s == '\n')
break;
s++;
}
if (*s == '='){
/* Key found ! */
keyFound = true;
s++;
while (isspace(*s)){
if (*s == '\n')
break;
s++;
}
/* Copy data ! */
s += CopyData(data, s);
}
}
}
/* Increment current pointer until the end of current line */
while (*s != '\0' && *s != '\n')
s++;
pcurrent = s;
return keyFound;
}
long CIniFile::CopyData(char * data, char * s){
/* Returns the number of characters copied not including the terminating null char */
char *pdata = data;
while (*s != '\0' && *s != '\r' && *s != '\n'){
*pdata = *s;
pdata++;
s++;
/* @@ Overflow @@
n++;
if (n == n_max){
*data = '\0';
return
}*/
}
*pdata = '\0';
return (pdata-data);
}
char * CIniFile::SkipUnwanted(char *s){
for ( ; ; ){
/* End of buffer ? */
if (*s == '\0')
return s;
if (isspace(*s)){
/* Skip spaces */
s++;
}else if (*s == ';'){
/* Skip comments */
char * end_of_line = strchr(s, '\n');
if (end_of_line){
/* End of comment */
s = end_of_line+1;
continue;
}else{
/* End of buffer */
return end_of_line;
}
/* Done */
}else{
return s;
}
}
}
/********************************************************************
* Class: CShellDlg.
*
* Purpose:
*
* Revisions:
*
********************************************************************/
CShellDlg::CShellDlg(){
// Get shell task allocator.
if(SHGetMalloc(&pMalloc) == (HRESULT) E_FAIL)
pMalloc = NULL;
}
CShellDlg::~CShellDlg(){
// Decrements the reference count.
if (pMalloc)
pMalloc->Release();
}
bool CShellDlg::BrowseForFolder(CWindow * pWindow, LPSTR pszDisplayName,
LPCSTR lpszTitle, UINT ulFlags, BFFCALLBACK lpfn, LPARAM lParam, int iImage){
// Initialize output buffer.
*pszDisplayName = '\0';
// BROWSEINFO.
if (!pWindow)
bi.hwndOwner = 0;
else
bi.hwndOwner = pWindow->_hWnd;
bi.pidlRoot = NULL;
bi.pszDisplayName = pszDisplayName;
bi.lpszTitle = lpszTitle;
bi.ulFlags = ulFlags;
bi.lpfn = lpfn;
bi.lParam = lParam;
bi.iImage = iImage;
LPITEMIDLIST pidl = SHBrowseForFolder(&bi);
if(!pidl)
return false;
if(!SHGetPathFromIDList(pidl, pszDisplayName))
return false;
pMalloc->Free(pidl);
return true;
}
CCriticalSection::CCriticalSection(){
::InitializeCriticalSection(&cs);
}
CCriticalSection::~CCriticalSection(){
::DeleteCriticalSection(&cs);
}
void CCriticalSection::Enter(){
::EnterCriticalSection(&cs);
}
void CCriticalSection::Leave(){
::LeaveCriticalSection(&cs);
}