complete nesting submodule

This commit is contained in:
itsmattkc 2022-03-31 11:38:16 -07:00
parent 5158c8ecb7
commit 8373301d1c
45 changed files with 6340 additions and 1 deletions

@ -1 +0,0 @@
Subproject commit 7f40af32bc7f121078d3c2b90a2656146d65cb3a

2
ext/PropertyGrid/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
build*/
*.user

View file

@ -0,0 +1,36 @@
cmake_minimum_required(VERSION 3.5)
project(PropertyGrid LANGUAGES CXX)
set(CMAKE_MFC_FLAG 2)
add_compile_definitions(_AFXDLL)
option(PROPERTYGRID_BUILD_APP "Build with test application" ON)
add_library(PropertyGrid STATIC
CustomItem.h
DynDialogEx.cpp
DynDialogEx.h
DynDialogItemEx.cpp
DynDialogItemEx.h
ListDynDialogEx.cpp
ListDynDialogEx.h
PropertyGrid.cpp
PropertyGrid.h
PropertyGridCombo.cpp
PropertyGridCombo.h
PropertyGridDirectoryPicker.cpp
PropertyGridDirectoryPicker.h
PropertyGridInPlaceEdit.cpp
PropertyGridInPlaceEdit.h
PropertyGridMonthCalCtrl.cpp
PropertyGridMonthCalCtrl.h
stdafx.cpp
stdafx.h
)
target_link_libraries(PropertyGrid PRIVATE shlwapi.lib)
if (PROPERTYGRID_BUILD_APP)
add_subdirectory(test)
endif()

View file

@ -0,0 +1,32 @@
#pragma once
#include "PropertyGrid.h"
class ICustomItem
{
public:
// basic required stuff
virtual CPropertyGrid::EEditMode GetEditMode() = 0;
virtual void DrawItem(CDC& dc, CRect rc, bool focused) = 0;
// validation
virtual void ValidateChanges() {}
// mouse stuff
virtual bool OnLButtonDown(CRect rc, CPoint pt) { return false; }
virtual void OnMouseMove(CRect rc, CPoint pt) {}
virtual void OnLButtonUp(CRect rc, CPoint pt) {}
// in-place edit
virtual string GetStringForInPlaceEdit() { return ""; }
virtual bool OnItemEdited(string strNewValue) { return false; }
// dropdown edit
virtual void ShowDropDown(CRect rc) {}
// modal edit
virtual bool OnEditItem() { return false; }
protected:
friend class CPropertyGrid;
CPropertyGrid* m_pGrid;
};

View file

@ -0,0 +1,610 @@
// DynDialogItemEx.cpp: implementation of the CDynDialogItemEx class.
//
// Written by Marcel Scherpenisse
// mailto:Marcel_Scherpenisse@insad.nl
//
// This code may be used in compiled form in any way you desire. This
// file may be redistributed unmodified by any means PROVIDING it is
// not sold for profit without the authors written consent, and
// providing that this notice and the authors name and all copyright
// notices remains intact. If the source code in this file is used in
// any commercial application then a statement along the lines of
// "Portions copyright (c) Marcel Scherpenisse, 2002" must be included in
// the startup banner, "About" box or printed documentation. An email
// letting me know that you are using it would be nice as well.
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability for any damage/loss of business that
// this product may cause.
//
// Expect bugs!
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "DynDialogEx.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CDynDialogEx dialog
CDynDialogEx::CDynDialogEx(CWnd* pParent /*=NULL*/)
: CDialog()
{
//{{AFX_DATA_INIT(CDynDialogEx)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
m_DialogTemplate.style = WS_CAPTION | WS_SYSMENU | WS_VISIBLE | DS_SETFONT;
m_DialogTemplate.dwExtendedStyle = WS_EX_DLGMODALFRAME;
m_DialogTemplate.x = 0;
m_DialogTemplate.y = 0;
m_DialogTemplate.cx = 0; // 4 horizontal units are the width of one character
m_DialogTemplate.cy = 0; // 8 vertical units are the height of one character
m_DialogTemplate.cdit = 0; // nr of dialog items in the dialog
m_pParentWnd = pParent;
m_strCaption = _T("");
m_pFont = NULL;
m_wFontSize = 0;
m_nCurRow = FIRSTROW1;
m_bAddSystemButtons = TRUE;
m_bIsFontCreated = FALSE;
m_bModelessDlg = FALSE;
}
CDynDialogEx::~CDynDialogEx()
{
CDynDialogItemEx *pDynDialogItemEx = NULL;
for (INT_PTR i = m_arrDlgItemPtr.size() - 1; i >= 0; i--) {
pDynDialogItemEx = m_arrDlgItemPtr[i];
if (pDynDialogItemEx != NULL) {
delete pDynDialogItemEx;
pDynDialogItemEx = NULL;
}
}
if (m_bIsFontCreated) {
delete m_pFont;
}
}
CWnd *CDynDialogEx::GetParent()
{
return m_pParentWnd;
}
void CDynDialogEx::AddStyles(DWORD dwStyles)
{
m_DialogTemplate.style |= dwStyles;
}
void CDynDialogEx::RemoveStyles(DWORD dwStyles)
{
m_DialogTemplate.style &= (~dwStyles);
}
void CDynDialogEx::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CDynDialogEx)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
CDynDialogItemEx *pDynDialogItemEx = NULL;
for (INT_PTR i = m_arrDlgItemPtr.size() - 1; i >= 0; i--) {
pDynDialogItemEx = m_arrDlgItemPtr[i];
if (pDynDialogItemEx != NULL) {
pDynDialogItemEx->DoDataExchange(pDX);
}
}
}
BEGIN_MESSAGE_MAP(CDynDialogEx, CDialog)
//{{AFX_MSG_MAP(CDynDialogEx)
ON_WM_CREATE()
//}}AFX_MSG_MAP
ON_MESSAGE(WM_HELP, OnHelpMsg)
ON_WM_MEASUREITEM() // TMB! 06-12-2001 Adjusted.. was wrongly an ON_MESSAGE()!!
ON_WM_DRAWITEM() // TMB! 06-12-2001 Adjusted.. was wrongly an ON_MESSAGE()!!
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDynDialogEx message handlers
int CDynDialogEx::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CDialog::OnCreate(lpCreateStruct) == -1)
return -1;
//if we have no font, create one here
if (m_pFont == NULL) {
LOGFONT LogFont;
// Can do better???
memset(&LogFont, 0x00, sizeof(LogFont));
strncpy(LogFont.lfFaceName, _T("MS Sans Serif"), LF_FACESIZE);
LogFont.lfHeight = 8;
m_pFont = new CFont;
m_pFont->CreateFontIndirect(&LogFont);
SetFont(m_pFont);
m_bIsFontCreated = TRUE;
}
//Create all the controls on the dialog
CDynDialogItemEx *pDynDialogItemEx = NULL;
for (int i = 0; i < m_arrDlgItemPtr.size(); i++) {
pDynDialogItemEx = m_arrDlgItemPtr[i];
if (pDynDialogItemEx != NULL) {
if (!pDynDialogItemEx->IsDlgItemSubclassed()) {
if (!pDynDialogItemEx->CreateEx(this)) {
AfxMessageBox(_T("Failed to create DlgItem."));
}
else if (pDynDialogItemEx->GetSafeHwnd() != NULL) {
pDynDialogItemEx->SetFont(m_pFont, FALSE);
}
}
}
}
return 0;
}
BOOL CDynDialogEx::OnInitDialog()
{
//Reposition all the controls on the dialog...
CDynDialogItemEx *pDynDialogItemEx = NULL;
for (int i = 0; i < m_arrDlgItemPtr.size(); i++) {
pDynDialogItemEx = m_arrDlgItemPtr[i];
if (pDynDialogItemEx != NULL) {
if (!pDynDialogItemEx->IsDlgItemSubclassed() && !pDynDialogItemEx->SetWindowPos(this)) {
CString strMessage;
strMessage.Format(_T("Failed SetWindowPos for control %s."), pDynDialogItemEx->GetClassName());
AfxMessageBox(strMessage);
}
}
}
CDialog::OnInitDialog();
CenterWindow();
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
int CDynDialogEx::DoModal()
{
//Do we need OK and Cancel buttons??
if (m_bAddSystemButtons) {
AddSystemButtons();
}
//
// Get font info from mainwindow of the application
//
CFont* pParentFont = m_pFont;
if (pParentFont == NULL && m_pParentWnd != NULL) {
pParentFont = m_pParentWnd->GetFont();
}
if (pParentFont == NULL && AfxGetApp()->m_pActiveWnd != NULL) {
pParentFont = AfxGetApp()->m_pActiveWnd->GetFont();
}
LOGFONT LogFont;
memset(&LogFont, 0x00, sizeof(LogFont));
if (pParentFont != NULL) {
pParentFont->GetLogFont(&LogFont);
}
else {
// Can do better???
strncpy(LogFont.lfFaceName, _T("MS Sans Serif"), LF_FACESIZE);
LogFont.lfHeight = 8;
}
//Prework for setting font in dialog...
int cWC = MultiByteToWideChar(CP_ACP, 0, LogFont.lfFaceName, -1, NULL, 0);
int nFontNameLen = cWC + 1;
WCHAR *szFontName = new WCHAR[nFontNameLen];
// Copy the string
MultiByteToWideChar(CP_ACP, 0, LogFont.lfFaceName, -1, (LPWSTR) szFontName, cWC);
szFontName[cWC] = 0;
nFontNameLen = (cWC) * sizeof(WCHAR);
if (m_wFontSize == 0) {
m_wFontSize = (unsigned short)LogFont.lfHeight;
}
//Prework for setting caption in dialog...
cWC = MultiByteToWideChar(CP_ACP, 0, m_strCaption, -1, NULL, 0);
int szBoxLen = cWC + 1;
WCHAR *szBoxCaption = new WCHAR[szBoxLen];
// Copy the string
MultiByteToWideChar(CP_ACP, 0, m_strCaption, -1, (LPWSTR) szBoxCaption, cWC);
szBoxCaption[cWC] = 0;
szBoxLen = (cWC) * sizeof(WCHAR);
INT_PTR iRet = -1;
//Here 's the stuff to build the dialog template in memory
//without the controls being in the template
//(Our first try, was this same template with some additional code
//for each control placed on it, that's why this class is cold Ex :)
//This gave some problems on WIN9x systems, where EDIT boxes
//were not shown with 3D-look, but as flat controls)
int nBufferSize = sizeof(DLGTEMPLATE) + (2 * sizeof(WORD)) /*menu and class*/ + szBoxLen /*size of caption*/
+ sizeof(WORD) /*fontsize*/ + nFontNameLen /*size of fontname*/;
//Are there any subclassed controls...
if (m_DialogTemplate.cdit > 0) {
nBufferSize = (nBufferSize + 3) & ~3; // adjust size to make first control DWORD aligned
CDynDialogItemEx *pDynDialogItemEx = NULL;
for (int i = 0; i < m_arrDlgItemPtr.size(); i++) {
pDynDialogItemEx = m_arrDlgItemPtr[i];
if (pDynDialogItemEx != NULL) {
if (pDynDialogItemEx->IsDlgItemSubclassed()) {
int nItemLength = sizeof(DLGITEMTEMPLATE) + 3 * sizeof(WORD);
nItemLength += (pDynDialogItemEx->GetCaptionLength() + 1) * sizeof(WCHAR);
if (i != m_DialogTemplate.cdit - 1) { // the last control does not need extra bytes
nItemLength = (nItemLength + 3) & ~3; // take into account gap so next control is DWORD aligned
}
nBufferSize += nItemLength;
}
}
}
}
HLOCAL hLocal = LocalAlloc(LHND, nBufferSize);
if (hLocal != NULL) {
BYTE* pBuffer = (BYTE*)LocalLock(hLocal);
if (pBuffer == NULL) {
LocalFree(hLocal);
AfxMessageBox(_T("CDynDialogEx::DoModal() : LocalLock Failed"));
}
BYTE *pdest = pBuffer;
// transfer DLGTEMPLATE structure to the buffer
memcpy(pdest, &m_DialogTemplate, sizeof(DLGTEMPLATE)); // DLGTemplate
pdest += sizeof(DLGTEMPLATE);
*(WORD*)pdest = 0; // no menu -- WORD to say it is 0 bytes
pdest += sizeof(WORD); // Increment
*(WORD*)(pdest + 1) = 0; // use default window class -- WORD to say it is 0 bytes
pdest += sizeof(WORD); // Increment
memcpy(pdest, szBoxCaption, szBoxLen); // Caption
pdest += szBoxLen;
*(WORD*)pdest = m_wFontSize; // font size
pdest += sizeof(WORD);
memcpy(pdest, szFontName, nFontNameLen); // font name
pdest += nFontNameLen;
// will now transfer the information for each one of subclassed controls...
if (m_DialogTemplate.cdit > 0) {
CDynDialogItemEx *pDynDialogItemEx = NULL;
for (int i = 0; i < m_arrDlgItemPtr.size(); i++) {
pDynDialogItemEx = m_arrDlgItemPtr[i];
if (pDynDialogItemEx != NULL) {
if (pDynDialogItemEx->IsDlgItemSubclassed()) {
pdest = pDynDialogItemEx->FillBufferWithItemTemplate(pdest);
}
}
}
}
ASSERT(pdest - pBuffer == nBufferSize); // just make sure we did not overrun the heap
//Next lines to make sure that MFC makes no ASSERTION when PREVIOUS/NEXT is pressed:)
if (m_lpDialogTemplate != NULL) {
m_lpDialogTemplate = NULL;
}
//These are the MFC functions, which do the job...
if (m_bModelessDlg) {
iRet = CreateIndirect((LPDLGTEMPLATE)pBuffer, m_pParentWnd);
}
else {
InitModalIndirect((LPDLGTEMPLATE)pBuffer, m_pParentWnd);
iRet = CDialog::DoModal();
}
LocalUnlock(hLocal);
LocalFree(hLocal);
delete [] szBoxCaption;
delete [] szFontName;
return iRet;
}
else {
AfxMessageBox(_T("CDynDialogEx::DoModal() : LocalAllock Failed"));
return -1;
}
}
void CDynDialogEx::SetFont(CFont *pFont)
{
m_pFont = pFont;
}
CFont *CDynDialogEx::GetFont()
{
return m_pFont;
}
void CDynDialogEx::SetFontSize(WORD wSize)
{
m_wFontSize = wSize;
}
WORD CDynDialogEx::GetFontSize()
{
return m_wFontSize;
}
void CDynDialogEx::SetUseSystemButtons(BOOL bUse /*= TRUE*/)
{
m_bAddSystemButtons = bUse;
}
void CDynDialogEx::GetDlgRect(LPRECT lpRect)
{
ASSERT(lpRect);
lpRect->left = m_DialogTemplate.x;
lpRect->top = m_DialogTemplate.y;
lpRect->right = lpRect->left + m_DialogTemplate.cx;
lpRect->bottom = lpRect->top + m_DialogTemplate.cy;
}
void CDynDialogEx::SetDlgRect(LPRECT lpRect)
{
ASSERT(lpRect);
//#pragma warning(disable : 4244)
m_DialogTemplate.cx = (short)(lpRect->right - lpRect->left);
m_DialogTemplate.cy = (short)(lpRect->bottom - lpRect->top);
m_DialogTemplate.x = (short)(lpRect->left);
m_DialogTemplate.y = (short)(lpRect->top);
//#pragma warning(default : 4244)
}
void CDynDialogEx::SetDlgRectangle(LPRECT pRect)
{
RECT rect;
GetDlgRect(&rect);
if (rect.left > pRect->left) {
rect.left = pRect->left;
}
if (rect.right < pRect->right) {
rect.right = pRect->right + 5;
}
if (rect.top > pRect->top) {
rect.top = pRect->top;
}
if (rect.bottom < pRect->bottom) {
rect.bottom = pRect->bottom + 5;
}
SetDlgRect(&rect);
}
UINT CDynDialogEx::AddDlgControl(DLGITEMTEMPLATECONTROLS TypeControl,
LPCTSTR lpszCaption,
DWORD dwStyle,
DWORD dwExtendedStyle,
LPRECT pRect /*= NULL*/,
void *pData /*= NULL*/,
UINT nID /*= 0*/)
{
UINT nRet = 0;
//In case no rectangle given create our own...
CRect Rect(FIXEDCOL1, m_nCurRow, FIXEDCOL2, m_nCurRow + ROWSTEPSIZE);
//if no rectangle given use our own...
if (pRect == NULL) {
pRect = &Rect;
}
// else {
// m_nCurRow = max(m_nCurRow, pRect->bottom) - m_nCurRow;
// }
m_nCurRow += (ROWSTEPSIZE);
//Update dialogtemplate boundaries
SetDlgRectangle(pRect);
//Create control and add to array of controls
CDynDialogItemEx *pDynDialogItemEx = new CDynDialogItemEx;
if (pDynDialogItemEx != NULL) {
nRet = pDynDialogItemEx->InitDialogItem(TypeControl, dwStyle, dwExtendedStyle, pRect, lpszCaption, nID, FALSE, pData);
m_arrDlgItemPtr.push_back(pDynDialogItemEx);
}
//Return ID of Control we created.
return nRet;
}
UINT CDynDialogEx::AddDlgControl(LPCSTR lpszClassName,
LPCTSTR lpszCaption,
DWORD dwStyle,
DWORD dwExtendedStyle,
LPRECT pRect /*= NULL*/,
void *pData /*= NULL*/,
UINT nID /*= 0*/)
{
UINT nRet = 0;
//In case no rectangle given create our own...
CRect Rect(FIXEDCOL1, m_nCurRow, FIXEDCOL2, m_nCurRow + ROWSTEPSIZE);
//if no rectangle given use our own...
if (pRect == NULL) {
pRect = &Rect;
Rect.right += INPUTCOL;
}
// else {
// m_nCurRow = max(m_nCurRow, pRect->bottom) - m_nCurRow;
// }
m_nCurRow += (ROWSTEPSIZE);
//Update dialogtemplate boundaries
SetDlgRectangle(pRect);
//Create control and add to array of controls
CDynDialogItemEx *pDynDialogItemEx = new CDynDialogItemEx;
if (pDynDialogItemEx != NULL) {
nRet = pDynDialogItemEx->InitDialogItem(lpszClassName, dwStyle, dwExtendedStyle, pRect, lpszCaption, nID, FALSE, pData);
m_arrDlgItemPtr.push_back(pDynDialogItemEx);
}
//Return ID of Control we created.
return nRet;
}
UINT CDynDialogEx::AddSubclassedDlgControl(LPCSTR lpszClassName,
LPCTSTR lpszCaption,
DWORD dwStyle,
DWORD dwExtendedStyle,
LPRECT pRect /*= NULL*/,
UINT nID /*= 0*/)
{
UINT nRet = 0;
//In case no rectangle given create our own...
CRect Rect(FIXEDCOL1, m_nCurRow, FIXEDCOL2, m_nCurRow + ROWSTEPSIZE);
//if no rectangle given use our own...
if (pRect == NULL) {
pRect = &Rect;
Rect.right += INPUTCOL;
}
// else {
// m_nCurRow = max(m_nCurRow, pRect->bottom) - m_nCurRow;
// }
m_nCurRow += (ROWSTEPSIZE);
//Update dialogtemplate boundaries
SetDlgRectangle(pRect);
//Create control and add to array of controls
CDynDialogItemEx *pDynDialogItemEx = new CDynDialogItemEx;
if (pDynDialogItemEx != NULL) {
nRet = pDynDialogItemEx->InitDialogItem(lpszClassName, dwStyle, dwExtendedStyle, pRect, lpszCaption, nID, TRUE);
m_arrDlgItemPtr.push_back(pDynDialogItemEx);
m_DialogTemplate.cdit++;
}
//Return ID of Control we created.
return nRet;
}
void CDynDialogEx::AddSystemButtons()
{
m_nCurRow += 6; // Leave some room!
CRect rect(FIXEDCOL1, m_nCurRow, FIXEDCOL2 - 60, m_nCurRow + (long)(ROWSTEPSIZE * 1.2));
AddDlgControl(BUTTON, _T("OK"), STYLE_BUTTON, EXSTYLE_BUTTON, &rect, NULL, IDOK);
// This has to be revised later.
rect.left += 55;
rect.right += 55;
AddDlgControl(BUTTON, _T("Annuleren"), STYLE_BUTTON, EXSTYLE_BUTTON, &rect, NULL, IDCANCEL);
}
void CDynDialogEx::SetWindowTitle(LPCSTR lpszCaption)
{
m_strCaption = lpszCaption;
}
void CDynDialogEx::SetUseModeless(BOOL bModelessDlg /*= TRUE*/)
{
m_bModelessDlg = bModelessDlg;
}
void CDynDialogEx::OnCancel()
{
if (m_bModelessDlg) {
DestroyWindow();
}
else {
CDialog::OnCancel();
}
}
void CDynDialogEx::OnOK()
{
if (m_bModelessDlg) {
DestroyWindow();
}
else {
CDialog::OnOK();
}
}
BOOL CDynDialogEx::OnCommand(WPARAM wParam, LPARAM lParam)
{
//wParam
//The low-order word of wParam identifies the command ID of the menu item, control, or accelerator.
//The high-order word of wParam specifies the notification message if the message is from a control.
//If the message is from an accelerator, the high-order word is 1.
//If the message is from a menu, the high-order word is 0.
//lParam
//Identifies the control that sends the message if the message is from a control. Otherwise, lParam is 0.
WORD wControlID = LOWORD(wParam);
WORD wMessageID = HIWORD(wParam);
if (wControlID != 0) {
switch (wControlID) {
case IDOK:
OnOK();
return TRUE;
break;
case IDCANCEL:
OnCancel();
return TRUE;
break;
default:
//if we have a parent send the message to the parent, so we can handle the message over there.
if (m_pParentWnd != NULL) {
::SendMessage(m_pParentWnd->GetSafeHwnd(), WM_COMMAND, wParam, lParam);
}
break;
}
}
return CDialog::OnCommand(wParam, lParam);
}
// Hellup!
afx_msg LRESULT CDynDialogEx::OnHelpMsg(WPARAM wParam, LPARAM lParam)
{
//lParam <<-- Contains: (LPHELPINFO)lParam
// >> typedef struct tagHELPINFO {
// UINT cbSize;
// int iContextType
// int iCtrlId;
// HANDLE hItemHandle;
// DWORD dwContextId;
// POINT MousePos;
// } HELPINFO, FAR *LPHELPINFO;
//
// User pressed F1 in dialog, call the OnHelp() function, this can be overridden...
//
OnHelp();
return TRUE;
}
// Default implementation of the OnHelp()
// This one is to be overridden by a caller ;)
void CDynDialogEx::OnHelp()
{
CDialog::OnHelp();
}

View file

@ -0,0 +1,160 @@
#if !defined(AFX_DYNDIALOGEX_H__CF5AF5E8_BD00_11D3_AA7C_0008C7083CA9__INCLUDED_)
#define AFX_DYNDIALOGEX_H__CF5AF5E8_BD00_11D3_AA7C_0008C7083CA9__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// DynDialogEx.h : header file
//
#include <VECTOR>
#include "DynDialogItemEx.h"
// Control styles
#define STYLE_EDIT (WS_VISIBLE | WS_CHILD | WS_TABSTOP | SS_LEFT)
#define STYLE_MULTIEDIT (WS_VISIBLE | WS_CHILD | WS_TABSTOP | SS_LEFT | ES_MULTILINE | ES_AUTOVSCROLL | WS_VSCROLL | ES_WANTRETURN)
#define STYLE_STATIC (WS_VISIBLE | WS_CHILD | SS_LEFT)
#define STYLE_STATIC_CENTER (WS_VISIBLE | WS_CHILD | SS_CENTER)
#define STYLE_STATIC_RIGHT (WS_VISIBLE | WS_CHILD | SS_RIGHT)
#define STYLE_RADIO (WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON)
#define STYLE_RADIO_GROUP (STYLE_RADIO| WS_GROUP | WS_TABSTOP)
#define STYLE_BUTTON (WS_VISIBLE | WS_CHILD | WS_TABSTOP | BS_PUSHBUTTON)
#define STYLE_GROUPBOX (WS_VISIBLE | WS_CHILD | BS_GROUPBOX)
#define STYLE_CHECKBOX (WS_VISIBLE | WS_CHILD | WS_TABSTOP | WS_GROUP | BS_AUTOCHECKBOX)
#define STYLE_COMBOBOX_DROPDOWN (WS_VISIBLE | WS_CHILD | WS_TABSTOP | WS_GROUP | WS_VSCROLL | CBS_DROPDOWN | CBS_SORT | CBS_AUTOHSCROLL) // | CBS_DISABLENOSCROLL)
#define STYLE_COMBOBOX_DROPDOWN_NOSORT (WS_VISIBLE | WS_CHILD | WS_TABSTOP | WS_GROUP | WS_VSCROLL | CBS_DROPDOWN | CBS_AUTOHSCROLL) // | CBS_DISABLENOSCROLL)
#define STYLE_COMBOBOX_SIMPLE (WS_VISIBLE | WS_CHILD | WS_TABSTOP | WS_GROUP | WS_VSCROLL | CBS_SIMPLE | CBS_SORT | CBS_AUTOHSCROLL) // | CBS_DISABLENOSCROLL)
#define STYLE_COMBOBOX_SIMPLE_NOSORT (WS_VISIBLE | WS_CHILD | WS_TABSTOP | WS_GROUP | WS_VSCROLL | CBS_SIMPLE | CBS_AUTOHSCROLL) // | CBS_DISABLENOSCROLL)
#define STYLE_COMBOBOX_DROPDOWNLIST (WS_VISIBLE | WS_CHILD | WS_TABSTOP | WS_GROUP | WS_VSCROLL | CBS_DROPDOWNLIST | CBS_SORT | CBS_AUTOHSCROLL) // | CBS_DISABLENOSCROLL)
#define STYLE_COMBOBOX_DROPDOWNLIST_NOSORT (WS_VISIBLE | WS_CHILD | WS_TABSTOP | WS_GROUP | WS_VSCROLL | CBS_DROPDOWNLIST | CBS_AUTOHSCROLL) // | CBS_DISABLENOSCROLL)
#define STYLE_LISTBOX (WS_VISIBLE | WS_CHILD | WS_TABSTOP | LBS_STANDARD)
#define STYLE_DATETIMEPICKER (WS_VISIBLE | WS_CHILD | WS_TABSTOP | DTS_RIGHTALIGN)
#define STYLE_TIMEPICKER (WS_VISIBLE | WS_CHILD | WS_TABSTOP | DTS_RIGHTALIGN | DTS_TIMEFORMAT)
// Default combo-style
#define STYLE_COMBOBOX (STYLE_COMBOBOX_DROPDOWNLIST)
#define STYLE_COMBOBOX_NOSORT (STYLE_COMBOBOX_DROPDOWNLIST_NOSORT)
// Control Extended styles
#define EXSTYLE_EDIT (WS_EX_CLIENTEDGE)
#define EXSTYLE_MULTIEDIT (WS_EX_CLIENTEDGE)
#define EXSTYLE_LISTBOX (WS_EX_CLIENTEDGE)
#define EXSTYLE_STATIC (0)
#define EXSTYLE_RADIO (0)
#define EXSTYLE_BUTTON (0)
#define EXSTYLE_GROUPBOX (0)
#define EXSTYLE_CHECKBOX (0)
#define EXSTYLE_COMBOBOX (0)
#define EXSTYLE_DATETIMEPICKER (0)
#define EXSTYLE_TIMEPICKER (0)
#define ROWSTEPSIZE 12
#define FIRSTROW1 10
#define FIRSTROW2 37
#define FIXEDCOL1 10
#define FIXEDCOL2 120
#define INPUTCOL 150
#define GROWLIMIT 6
#define MAX_COLS_PER_DESCR 25 // Just a number..
/////////////////////////////////////////////////////////////////////////////
// CDynDialogEx dialog
class CDynDialogEx : public CDialog
{
// Construction
public:
CDynDialogEx(CWnd* pParent = NULL); // standard constructor
~CDynDialogEx();
virtual CWnd *GetParent();
// Dialog Data
//{{AFX_DATA(CDynDialogEx)
// NOTE: the ClassWizard will add data members here
//}}AFX_DATA
virtual UINT AddDlgControl(DLGITEMTEMPLATECONTROLS TypeControl,
LPCTSTR lpszCaption,
DWORD dwStyle,
DWORD dwExtendedStyle,
LPRECT pRect = NULL,
void *pData = NULL,
UINT nID = 0);
virtual UINT AddDlgControl(LPCSTR lpszClassName,
LPCTSTR lpszCaption,
DWORD dwStyle,
DWORD dwExtendedStyle,
LPRECT pRect = NULL,
void *pData = NULL,
UINT nID = 0);
virtual UINT AddSubclassedDlgControl(LPCSTR lpszClassName,
LPCTSTR lpszCaption,
DWORD dwStyle,
DWORD dwExtendedStyle,
LPRECT pRect = NULL,
UINT nID = 0);
void SetWindowTitle(LPCSTR lpszCaption);
void SetFont(CFont *pFont);
CFont *GetFont();
void SetFontSize(WORD wSize);
WORD GetFontSize();
void SetUseSystemButtons(BOOL bUse = TRUE);
void SetUseModeless(BOOL bModelessDlg = TRUE);
long GetNumberOfConrols() {return long(m_arrDlgItemPtr.size());}
//Additional functions by Tom Daffin
void AddStyles(DWORD dwStyles);
void RemoveStyles(DWORD dwStyles);
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CDynDialogEx)
public:
virtual int DoModal();
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
virtual void OnCancel();
virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);
virtual void OnOK();
//}}AFX_VIRTUAL
virtual void OnHelp(); // To be overridden..
protected:
CWnd *m_pParentWnd;
CString m_strCaption;
CFont *m_pFont;
WORD m_wFontSize;
long m_nCurRow;
BOOL m_bAddSystemButtons;
BOOL m_bIsFontCreated;
BOOL m_bModelessDlg;
DLGTEMPLATE m_DialogTemplate;
// DOWNGRADE: Switch from CArray to std::vector because MFC 4.2 doesn't have CArray
std::vector<CDynDialogItemEx*> m_arrDlgItemPtr;
// Implementation
protected:
void AddSystemButtons();
void GetDlgRect(LPRECT lpRect);
void SetDlgRect(LPRECT lpRect);
void SetDlgRectangle(LPRECT pRect);
// Generated message map functions
//{{AFX_MSG(CDynDialogEx)
virtual BOOL OnInitDialog();
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
//}}AFX_MSG
afx_msg LRESULT OnHelpMsg(WPARAM wParam, LPARAM lParam);
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_DYNDIALOGEX_H__CF5AF5E8_BD00_11D3_AA7C_0008C7083CA9__INCLUDED_)

View file

@ -0,0 +1,534 @@
// DynDialogItemEx.cpp: implementation of the CDynDialogItemEx class.
//
// Written by Marcel Scherpenisse
// mailto:Marcel_Scherpenisse@insad.nl
//
// This code may be used in compiled form in any way you desire. This
// file may be redistributed unmodified by any means PROVIDING it is
// not sold for profit without the authors written consent, and
// providing that this notice and the authors name and all copyright
// notices remains intact. If the source code in this file is used in
// any commercial application then a statement along the lines of
// "Portions copyright (c) Marcel Scherpenisse, 2002" must be included in
// the startup banner, "About" box or printed documentation. An email
// letting me know that you are using it would be nice as well.
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability for any damage/loss of business that
// this product may cause.
//
// Expect bugs!
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "DynDialogItemEx.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
struct _RuntimeLicense {
LPCTSTR lpszRegisteredControlName;
WCHAR *wchLicenseKey;
long lLicenseLength;
}_TAGRUNTIMELICENSE;
/*mgkgtgnnmnmninigthkgogggvmkhinjggnvm*/ //(MS Multimedia MCI Control - mci32.ocx)
WCHAR pwchMCIMMControl1LicenseKey[] =
{
0x006D, 0x0067, 0x006B, 0x0067, 0x0074, 0x0067,
0x006E, 0x006E, 0x006D, 0x006E, 0x006D, 0x006E,
0x0069, 0x006E, 0x0069, 0x0067, 0x0074, 0x0068,
0x006B, 0x0067, 0x006F, 0x0067, 0x0067, 0x0067,
0x0076, 0x006D, 0x006B, 0x0068, 0x0069, 0x006E,
0x006A, 0x0067, 0x0067, 0x006E, 0x0076, 0x006D
};
/*Copyright (c) 1994 */ //(MS Communications Control - mscomm32.ocx)
WCHAR pwchMSCOMMLibMSComm1LicenseKey[] =
{
0x0043, 0x006F, 0x0070, 0x0079, 0x0072, 0x0069,
0x0067, 0x0068, 0x0074, 0x0020, 0x0028, 0x0063,
0x0029, 0x0020, 0x0031, 0x0039, 0x0039, 0x0034,
0x0020
};
/*72E67120-5959-11cf-91F6-C2863C385E30*/ //(MS Flex Grid Control - msflxgrd.ocx)
WCHAR pwchMSFlexGridLibMSFlexGrid1LicenseKey[] =
{
0x0037, 0x0032, 0x0045, 0x0036, 0x0037, 0x0031,
0x0032, 0x0030, 0x002D, 0x0035, 0x0039, 0x0035,
0x0039, 0x002D, 0x0031, 0x0031, 0x0063, 0x0066,
0x002D, 0x0039, 0x0031, 0x0046, 0x0036, 0x002D,
0x0043, 0x0032, 0x0038, 0x0036, 0x0033, 0x0043,
0x0033, 0x0038, 0x0035, 0x0045, 0x0033, 0x0030
};
/*mgkgtgnnmnmninigthkgogggvmkhinjggnvm*/ //(MS Masked Edit - msmask32.ocx)
WCHAR pwchMSMaskMaskEdBox1LicenseKey[] =
{
0x006D, 0x0067, 0x006B, 0x0067, 0x0074, 0x0067,
0x006E, 0x006E, 0x006D, 0x006E, 0x006D, 0x006E,
0x0069, 0x006E, 0x0069, 0x0067, 0x0074, 0x0068,
0x006B, 0x0067, 0x006F, 0x0067, 0x0067, 0x0067,
0x0076, 0x006D, 0x006B, 0x0068, 0x0069, 0x006E,
0x006A, 0x0067, 0x0067, 0x006E, 0x0076, 0x006D
};
/*GL........*/ //(MS Grid Control - grid32.ocx)
WCHAR pwchMSDBGridDBGridLicenseKey[] =
{
0x0047, 0x004C, 0x0005, 0x0008, 0x0001, 0x0005,
0x0002, 0x0008, 0x0001, 0x0004
};
/*DB4C0D09-400B-101B-A3C9-08002B2F49FB*/ //(MS Picture Clip Control - picclp32.ocx)
WCHAR pwchPicClipPictureClip1LicenseKey[] =
{
0x0044, 0x0042, 0x0034, 0x0043, 0x0030, 0x0044,
0x0030, 0x0039, 0x002D, 0x0034, 0x0030, 0x0030,
0x0042, 0x002D, 0x0031, 0x0030, 0x0031, 0x0042,
0x002D, 0x0041, 0x0033, 0x0043, 0x0039, 0x002D,
0x0030, 0x0038, 0x0030, 0x0030, 0x0032, 0x0042,
0x0032, 0x0046, 0x0034, 0x0039, 0x0046, 0x0042
};
/*04746E60CE4F11CDB23C0000C076FE*/ //(MS Tab Control - tabctl32.ocx)
static WCHAR pwchTabDlgSSTab1LicenseKey[] =
{
0x0030, 0x0034, 0x0037, 0x0034, 0x0036, 0x0045,
0x0036, 0x0030, 0x0043, 0x0045, 0x0034, 0x0046,
0x0031, 0x0031, 0x0043, 0x0044, 0x0042, 0x0032,
0x0033, 0x0043, 0x0030, 0x0030, 0x0030, 0x0030,
0x0043, 0x0030, 0x0037, 0x0036, 0x0046, 0x0045
};
static _RuntimeLicense RuntimeLicenses[] =
{
{_T("MCI.MMControl.1"), pwchMCIMMControl1LicenseKey, sizeof(pwchMCIMMControl1LicenseKey)},
{_T("MSCOMMLib.MSComm.1"), pwchMSCOMMLibMSComm1LicenseKey, sizeof(pwchMSCOMMLibMSComm1LicenseKey)},
{_T("MSFlexGridLib.MSFlexGrid.1"), pwchMSFlexGridLibMSFlexGrid1LicenseKey, sizeof(pwchMSFlexGridLibMSFlexGrid1LicenseKey)},
{_T("MSMask.MaskEdBox.1"), pwchMSMaskMaskEdBox1LicenseKey, sizeof(pwchMSMaskMaskEdBox1LicenseKey)},
{_T("MSDBGrid.DBGrid"), pwchMSDBGridDBGridLicenseKey, sizeof(pwchMSDBGridDBGridLicenseKey)},
{_T("PicClip.PictureClip.1"), pwchPicClipPictureClip1LicenseKey, sizeof(pwchPicClipPictureClip1LicenseKey)},
{_T("TabDlg.SSTab.1"), pwchTabDlgSSTab1LicenseKey, sizeof(pwchTabDlgSSTab1LicenseKey)},
{NULL, NULL, 0}
};
static UINT glb_nNextID = WM_USER; // We have to start somewhere...
UINT GetNewUniqueID(void)
{
glb_nNextID++;
return glb_nNextID - 1;
}
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CDynDialogItemEx::CDynDialogItemEx()
: CWnd()
{
m_eTypeControl = NOCONTROL;
m_strClassName = _T("");
m_dwStyle = 0;
m_dwStyleEx = 0;
m_strCaption = _T("");
m_ControlID = 0;
m_pData = NULL;
m_bSubclassed = FALSE;
}
void CDynDialogItemEx::DoDataExchange(CDataExchange *pDX)
{
if (m_pData != NULL) {
switch(m_eTypeControl) {
case BUTTON:
if ((m_dwStyle & BS_AUTORADIOBUTTON) == BS_AUTORADIOBUTTON) {
DDX_Radio(pDX, m_ControlID, *(int*)m_pData);
}
else if ((m_dwStyle & BS_AUTOCHECKBOX) == BS_AUTOCHECKBOX) {
DDX_Check(pDX, m_ControlID, *(int*)m_pData);
}
else {
DDX_Control(pDX, m_ControlID, *(CWnd*)m_pData);
}
break;
case EDITCONTROL:
DDX_Text(pDX, m_ControlID, *(CString*)m_pData);
break;
case STATICTEXT:
DDX_Text(pDX, m_ControlID, *(CString*)m_pData);
break;
case LISTBOX:
DDX_Control(pDX, m_ControlID, *(CWnd*)m_pData);
break;
case HSCROLL:
DDX_Scroll(pDX, m_ControlID, *(int*)m_pData);
break;
case COMBOBOX:
DDX_Control(pDX, m_ControlID, *(CWnd*)m_pData);
break;
case SPIN:
DDX_Control(pDX, m_ControlID, *(CWnd*)m_pData);
break;
case PROGRES:
DDX_Control(pDX, m_ControlID, *(CWnd*)m_pData);
break;
case SLIDER:
DDX_Slider(pDX, m_ControlID, *(int*)m_pData);
break;
case HOTKEY:
DDX_Control(pDX, m_ControlID, *(CWnd*)m_pData);
break;
case LISTCTRL:
DDX_Control(pDX, m_ControlID, *(CWnd*)m_pData);
break;
case TREECTRL:
DDX_Control(pDX, m_ControlID, *(CWnd*)m_pData);
break;
case TABCTRL:
DDX_Control(pDX, m_ControlID, *(CWnd*)m_pData);
break;
case ANIMATE:
DDX_Control(pDX, m_ControlID, *(CWnd*)m_pData);
break;
case RICHEDIT:
DDX_Control(pDX, m_ControlID, *(CWnd*)m_pData);
break;
case DATETIMEPICKER:
if ((m_dwStyle & DTS_TIMEFORMAT) == DTS_TIMEFORMAT) {
DDX_DateTimeCtrl(pDX, m_ControlID, *(CTime*)m_pData);
}
else {
DDX_DateTimeCtrl(pDX, m_ControlID, *(COleDateTime*)m_pData);
}
break;
case MONTHCALENDER:
DDX_MonthCalCtrl(pDX, m_ControlID, *(COleDateTime*)m_pData);
break;
case IPADRESS:
DDX_Control(pDX, m_ControlID, *(CWnd*)m_pData);
break;
case COMBOBOXEX:
DDX_Control(pDX, m_ControlID, *(CWnd*)m_pData);
break;
default:
break;
}
}
CWnd::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CDynDialogItemEx, CWnd)
//{{AFX_MSG_MAP(CDynDialogItemEx)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
char* CDynDialogItemEx::GetClassNameByType(DLGITEMTEMPLATECONTROLS TypeControl)
{
switch(TypeControl) {
case BUTTON:
return _T("BUTTON");
case EDITCONTROL:
return _T("EDIT");
case STATICTEXT:
return _T("STATIC");
case LISTBOX:
return _T("LISTBOX");
case HSCROLL:
return _T("SCROLLBAR");
case COMBOBOX:
return _T("COMBOBOX");
case SPIN:
return _T("msctls_updown32");
case PROGRES:
return _T("msctls_progress32");
case SLIDER:
return _T("msctls_trackbar32");
case HOTKEY:
return _T("msctls_hotkey32");
case LISTCTRL:
return _T("SysListView32");
case TREECTRL:
return _T("SysTreeView32");
case TABCTRL:
return _T("SysTabControl32");
case ANIMATE:
return _T("SysAnimate32");
case RICHEDIT:
return _T("RICHEDIT");
case DATETIMEPICKER:
return _T("SysDateTimePick32");
case MONTHCALENDER:
return _T("SysMonthCal32");
case IPADRESS:
return _T("SysIPAddress32");
case COMBOBOXEX:
return _T("ComboBoxEx32");
}
return _T("");
}
DLGITEMTEMPLATECONTROLS CDynDialogItemEx::GetClassTypeByName(LPCSTR lpszClassName)
{
if (memcmp(lpszClassName, _T("BUTTON"), 6) == 0) {
return BUTTON;
}
else if (memcmp(lpszClassName, _T("EDIT"), 4) == 0) {
return EDITCONTROL;
}
else if (memcmp(lpszClassName, _T("STATIC"), 6) == 0) {
return STATICTEXT;
}
else if (memcmp(lpszClassName, _T("LISTBOX"), 7) == 0) {
return LISTBOX;
}
else if (memcmp(lpszClassName, _T("SCROLLBAR"), 9) == 0) {
return HSCROLL;
}
else if (memcmp(lpszClassName, _T("COMBOBOX"), 8) == 0) {
return COMBOBOX;
}
else if (memcmp(lpszClassName, _T("msctls_updown32"), 15) == 0) {
return SPIN;
}
else if (memcmp(lpszClassName, _T("msctls_progress32"), 17) == 0) {
return PROGRES;
}
else if (memcmp(lpszClassName, _T("msctls_trackbar32"), 17) == 0) {
return SLIDER;
}
else if (memcmp(lpszClassName, _T("msctls_hotkey32"), 15) == 0) {
return HOTKEY;
}
else if (memcmp(lpszClassName, _T("SysListView32"), 13) == 0) {
return LISTCTRL;
}
else if (memcmp(lpszClassName, _T("SysTreeView32"), 13) == 0) {
return TREECTRL;
}
else if (memcmp(lpszClassName, _T("SysTabControl32"), 15) == 0) {
return TABCTRL;
}
else if (memcmp(lpszClassName, _T("SysAnimate32"), 12) == 0) {
return ANIMATE;
}
else if (memcmp(lpszClassName, _T("RICHEDIT"), 8) == 0) {
return RICHEDIT;
}
else if (memcmp(lpszClassName, _T("SysDateTimePick32"), 17) == 0) {
return DATETIMEPICKER;
}
else if (memcmp(lpszClassName, _T("SysMonthCal32"), 13) == 0) {
return MONTHCALENDER;
}
else if (memcmp(lpszClassName, _T("SysIPAddress32"), 14) == 0) {
return IPADRESS;
}
else if (memcmp(lpszClassName, _T("ComboBoxEx32"), 12) == 0) {
return COMBOBOXEX;
}
return NOCONTROL;
}
UINT CDynDialogItemEx::InitDialogItem(DLGITEMTEMPLATECONTROLS TypeControl,
DWORD dwStyle,
DWORD dwExtendedStyle,
LPRECT pRect,
LPCTSTR lpszCaption,
UINT nID /*= 0*/,
BOOL bSubclassed /*= FALSE*/,
void *pData /*= NULL*/)
{
m_eTypeControl = TypeControl;
m_strClassName = GetClassNameByType(m_eTypeControl);
m_dwStyle = dwStyle;
m_dwStyleEx = dwExtendedStyle;
m_Rect = pRect;
m_strCaption = lpszCaption;
m_bSubclassed = bSubclassed;
m_pData = pData;
if (nID == 0) {
m_ControlID = ::GetNewUniqueID();
}
else {
m_ControlID = nID;
}
return m_ControlID;
}
UINT CDynDialogItemEx::InitDialogItem(LPCSTR lpszClassName,
DWORD dwStyle,
DWORD dwExtendedStyle,
LPRECT pRect,
LPCTSTR lpszCaption,
UINT nID /*= 0*/,
BOOL bSubclassed /*= FALSE*/,
void *pData /*= NULL*/)
{
m_strClassName = lpszClassName;
m_eTypeControl = GetClassTypeByName(lpszClassName);
m_dwStyle = dwStyle;
m_dwStyleEx = dwExtendedStyle;
m_Rect = pRect;
m_strCaption = lpszCaption;
m_bSubclassed = bSubclassed;
m_pData = pData;
if (nID == 0) {
m_ControlID = ::GetNewUniqueID();
}
else {
m_ControlID = nID;
}
return m_ControlID;
}
BOOL CDynDialogItemEx::CreateEx(CWnd *pParent)
{
BOOL bRet = FALSE;
if (m_eTypeControl == NOCONTROL) { //It will probably be an OCX...
//
// Create the control later....
// if it's created here then the rectangle is not OK and SetWindowPos doesn't work on OCX's????
//
bRet = TRUE;
}
else if (m_pData != NULL && IsDataMemberPointerToWnd()) {
bRet = ((CWnd*)m_pData)->CreateEx(m_dwStyleEx, m_strClassName, m_strCaption, m_dwStyle, m_Rect, pParent, m_ControlID);
}
else {
bRet = CWnd::CreateEx(m_dwStyleEx, m_strClassName, m_strCaption, m_dwStyle, m_Rect, pParent, m_ControlID);
}
return bRet;
}
BOOL CDynDialogItemEx::SetWindowPos(CWnd *pParent)
{
BOOL bRet = FALSE;
//Conversion of Dialog units to screenunits
CRect rect(m_Rect);
((CDialog *)pParent)->MapDialogRect(&rect);
ASSERT(rect.IsRectEmpty() == FALSE);
if (m_eTypeControl == NOCONTROL) {
BSTR bstrLicKey = GetRuntimeLicense(m_strClassName);
bRet = CreateControl(m_strClassName, m_strCaption, m_dwStyle, rect, pParent, m_ControlID, NULL, FALSE, bstrLicKey);
if (bstrLicKey != NULL) {
::SysFreeString(bstrLicKey);
}
}
else if (m_pData != NULL && IsDataMemberPointerToWnd()) {
bRet = ((CWnd*)m_pData)->SetWindowPos(NULL, rect.left, rect.top, rect.Width(), rect.Height(), SWP_NOZORDER);
}
else {
bRet = CWnd::SetWindowPos(NULL, rect.left, rect.top, rect.Width(), rect.Height(), SWP_NOZORDER);
}
return bRet;
}
void CDynDialogItemEx::SetFont(CFont* pFont, BOOL bRedraw /*= TRUE*/)
{
if (m_pData != NULL && IsDataMemberPointerToWnd()) {
((CWnd*)m_pData)->SetFont(pFont, bRedraw);
}
else {
CWnd::SetFont(pFont, bRedraw);
}
}
PBYTE CDynDialogItemEx::FillBufferWithItemTemplate(BYTE *pdest)
{
pdest = (BYTE*)(((DWORD)pdest + 3) & ~3); // make the pointer DWORD aligned
DLGITEMTEMPLATE dlgItemTemplate;
dlgItemTemplate.x = (short)m_Rect.left;
dlgItemTemplate.y = (short)m_Rect.top;
dlgItemTemplate.cx = (short)m_Rect.Width();
dlgItemTemplate.cy = (short)m_Rect.Height();
dlgItemTemplate.style = m_dwStyle;
dlgItemTemplate.dwExtendedStyle = m_dwStyleEx;
dlgItemTemplate.id = (USHORT)m_ControlID;
memcpy(pdest, (void *)&dlgItemTemplate, sizeof(DLGITEMTEMPLATE));
pdest += sizeof(DLGITEMTEMPLATE);
*(WORD*)pdest = 0xFFFF; // indicating atom value
pdest += sizeof(WORD);
*(WORD*)pdest = (USHORT)m_eTypeControl; // atom value for the control
pdest += sizeof(WORD);
// transfer the caption even when it is an empty string
WCHAR* pchCaption;
int nChars, nActualChars;
nChars = m_strCaption.GetLength() + 1;
pchCaption = new WCHAR[nChars];
nActualChars = MultiByteToWideChar(CP_ACP, 0, m_strCaption, -1, pchCaption, nChars);
ASSERT(nActualChars > 0);
memcpy(pdest, pchCaption, nActualChars * sizeof(WCHAR));
pdest += nActualChars * sizeof(WCHAR);
delete pchCaption;
*(WORD*)pdest = 0; // How many bytes in data for control
pdest += sizeof(WORD);
return pdest;
}
BSTR CDynDialogItemEx::GetRuntimeLicense(CString &strControlName)
{
BSTR bstrLicKey = NULL;
int i = 0;
while (RuntimeLicenses[i].lpszRegisteredControlName != NULL) {
if (strControlName.Compare(RuntimeLicenses[i].lpszRegisteredControlName) == 0) {
bstrLicKey = ::SysAllocStringLen(RuntimeLicenses[i].wchLicenseKey, RuntimeLicenses[i].lLicenseLength/sizeof(WCHAR));
break;
}
i++;
}
return bstrLicKey;
}
BOOL CDynDialogItemEx::IsDataMemberPointerToWnd()
{
BOOL bRet = TRUE;
switch(m_eTypeControl)
{
case BUTTON:
if ((m_dwStyle & BS_AUTORADIOBUTTON) == BS_AUTORADIOBUTTON) {
bRet = FALSE;
}
else if ((m_dwStyle & BS_AUTOCHECKBOX) == BS_AUTOCHECKBOX) {
bRet = FALSE;
}
break;
case EDITCONTROL:
bRet = FALSE;
break;
case STATICTEXT:
bRet = FALSE;
break;
case HSCROLL:
bRet = FALSE;
break;
case SLIDER:
bRet = FALSE;
break;
case DATETIMEPICKER:
bRet = FALSE;
break;
case MONTHCALENDER:
bRet = FALSE;
break;
default:
break;
}
return bRet;
}

View file

@ -0,0 +1,107 @@
// DynDialogItemEx.h: interface for the CDynDialogItemEx class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_DYNDIALOGITEMEX_H__CF5AF5E9_BD00_11D3_AA7C_0008C7083CA9__INCLUDED_)
#define AFX_DYNDIALOGITEMEX_H__CF5AF5E9_BD00_11D3_AA7C_0008C7083CA9__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
typedef enum {
NOCONTROL = 0,
BUTTON = 0x0080,
EDITCONTROL = 0x0081,
STATICTEXT = 0x0082,
LISTBOX = 0x0083,
HSCROLL = 0x0084,
COMBOBOX = 0x0085,
SPIN,
PROGRES,
SLIDER,
HOTKEY,
LISTCTRL,
TREECTRL,
TABCTRL,
ANIMATE,
RICHEDIT,
DATETIMEPICKER,
MONTHCALENDER,
IPADRESS,
COMBOBOXEX
} DLGITEMTEMPLATECONTROLS;
class CDynDialogItemEx : public CWnd
{
public:
// Construction
CDynDialogItemEx();
// Operations
public:
UINT InitDialogItem(DLGITEMTEMPLATECONTROLS TypeControl,
DWORD dwStyle,
DWORD dwExtendedStyle,
LPRECT pRect,
LPCTSTR lpszCaption,
UINT nID = 0,
BOOL bSubclassed = FALSE,
void *pData = NULL);
UINT InitDialogItem(LPCSTR lpszClassName,
DWORD dwStyle,
DWORD dwExtendedStyle,
LPRECT pRect,
LPCTSTR lpszCaption,
UINT nID = 0,
BOOL bSubclassed = FALSE,
void *pData = NULL);
BOOL CreateEx(CWnd *pParent);
void SetFont(CFont* pFont, BOOL bRedraw = TRUE);
// Operations
public:
virtual void DoDataExchange(CDataExchange* pDX);
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CDynDialogItemEx)
//}}AFX_VIRTUAL
// Implementation
public:
//virtual ~CDynDialogItemEx();
BOOL SetWindowPos(CWnd *pParent);
PBYTE FillBufferWithItemTemplate(BYTE* pdest);
UINT GetControlID() {return m_ControlID;}
DLGITEMTEMPLATECONTROLS GetControlType() {return m_eTypeControl;}
long GetCaptionLength() {return m_strCaption.GetLength();}
BOOL IsDlgItemSubclassed() {return m_bSubclassed;}
CString GetClassName() {return m_strClassName;}
protected:
DLGITEMTEMPLATECONTROLS GetClassTypeByName(LPCSTR lpszClassName);
CString m_strClassName;
DLGITEMTEMPLATECONTROLS m_eTypeControl;
UINT m_ControlID;
UINT m_dwStyle;
UINT m_dwStyleEx;
CRect m_Rect;
CString m_strCaption;
void *m_pData;
BOOL m_bSubclassed;
// Generated message map functions
protected:
BOOL IsDataMemberPointerToWnd();
BSTR GetRuntimeLicense(CString &strControlName);
char* GetClassNameByType(DLGITEMTEMPLATECONTROLS TypeControl);
//{{AFX_MSG(CDynDialogItemEx)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
#endif // !defined(AFX_DYNDIALOGITEMEX_H__CF5AF5E9_BD00_11D3_AA7C_0008C7083CA9__INCLUDED_)

View file

@ -0,0 +1,59 @@
// ListDynDialogEx.cpp: implementation of the CListDynDialogEx class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "ListDynDialogEx.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#define IDC_LIST1 1600
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CListDynDialogEx::CListDynDialogEx(CWnd* pParent /*= NULL*/)
: CDynDialogEx(pParent)
{
m_bAddSystemButtons = FALSE;
}
CListDynDialogEx::~CListDynDialogEx()
{
}
BEGIN_MESSAGE_MAP(CListDynDialogEx, CDynDialogEx)
//{{AFX_MSG_MAP(CListDynDialogEx)
ON_LBN_DBLCLK(IDC_LIST1, OnDblclkList)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
BOOL CListDynDialogEx::OnInitDialog()
{
BOOL bRet = CDynDialogEx::OnInitDialog();
m_lstBox.AddString(_T("First String"));
m_lstBox.AddString(_T("Second String"));
return bRet;
}
int CListDynDialogEx::DoModal()
{
CRect rect(7,7,150,150);
AddDlgControl(_T("LISTBOX"), _T("ListboxText"), STYLE_LISTBOX, EXSTYLE_LISTBOX, &rect, &m_lstBox, IDC_LIST1);
return CDynDialogEx::DoModal();
}
void CListDynDialogEx::OnDblclkList()
{
CString strBuf;
int nIndex = m_lstBox.GetCurSel();
m_lstBox.GetText(nIndex, strBuf);
AfxMessageBox(strBuf);
OnOK();
}

View file

@ -0,0 +1,40 @@
// ListDynDialogEx.h: interface for the CListDynDialogEx class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_LISTDYNDIALOGEX_H__57BA7AFA_B679_4FAC_B6BE_1AD925E45194__INCLUDED_)
#define AFX_LISTDYNDIALOGEX_H__57BA7AFA_B679_4FAC_B6BE_1AD925E45194__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "dyndialogex.h"
class CListDynDialogEx : public CDynDialogEx
{
public:
CListDynDialogEx(CWnd* pParent = NULL);
virtual ~CListDynDialogEx();
CListBox m_lstBox;
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CListDynDialogEx)
public:
virtual int DoModal();
//}}AFX_VIRTUAL
// Implementation
protected:
// Generated message map functions
//{{AFX_MSG(CListDynDialogEx)
virtual BOOL OnInitDialog();
afx_msg void OnDblclkList();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
#endif // !defined(AFX_LISTDYNDIALOGEX_H__57BA7AFA_B679_4FAC_B6BE_1AD925E45194__INCLUDED_)

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,316 @@
#pragma once
#include "PropertyGridCombo.h"
#include "PropertyGridInPlaceEdit.h"
#include <map>
#include <vector>
#include <string>
using namespace std;
// CPropertyGrid
#define WM_PG_ITEMCHANGED WM_USER+486
#define WM_PG_SELECTIONCHANGED WM_USER+487
typedef UINT HSECTION;
typedef UINT HITEM;
class ICustomItem;
class CPropertyGrid : public CWnd
{
DECLARE_DYNAMIC(CPropertyGrid)
public:
// display mode
enum EDisplayMode
{
DM_CATEGORIZED = 0,
DM_ALPHABETICAL,
DM_NOSORT
};
// editing
enum EEditMode
{
EM_CUSTOM = 0,
EM_INPLACE,
EM_DROPDOWN,
EM_MODAL
};
enum EItemType
{
IT_CUSTOM = 0,
IT_STRING,
IT_TEXT,
IT_INTEGER,
IT_DOUBLE,
IT_COMBO,
IT_BOOLEAN,
IT_DATE,
IT_DATETIME,
IT_FILE,
IT_FOLDER,
IT_COLOR,
IT_FONT
};
public:
CPropertyGrid();
virtual ~CPropertyGrid();
// customization
bool GetShadeTitles();
void SetShadeTitles(bool shade_titles);
bool GetDrawLines();
void SetDrawLines(bool draw_lines);
bool GetDrawGutter();
void SetDrawGutter(bool draw_gutter);
bool GetFocusDisabled();
void SetFocusDisabled(bool focus_disabled);
bool GetBoldModified();
void SetBoldModified(bool bold_modified);
bool GetBoldEditables();
void SetBoldEditables(bool bold_editables);
// gutter width
int GetGutterWidth();
void SetGutterWidth(int gutter_width);
// custom colors
void SetTextColor(COLORREF clrText);
void SetTitleColor(COLORREF clrText);
void SetBackColor(COLORREF clrBack);
void SetShadeColor(COLORREF clrShade);
void SetFocusColor(COLORREF clrFocus);
void SetHiliteColor(COLORREF clrHilite);
void SetEditableColor(COLORREF clrEditable);
void SetDisabledColor(COLORREF clrDisabled);
// localization
void SetTrueFalseStrings(string strTrue, string strFalse);
void SetOkCancelStrings(string strOk, string strCancel);
void SetDateTimeStrings(string strDate, string strTime);
void SetUndefinedString(string strUndefined);
void SetEmptyString(string strEmpty);
// add a section
HSECTION AddSection(string title, bool collapsed = false, HSECTION after = -1);
// add items
HITEM AddCustomItem(HSECTION, string name, ICustomItem* pItem, bool editable = true, HITEM after = -1);
HITEM AddStringItem(HSECTION section, string name, string value, bool editable = true, HITEM after = -1);
HITEM AddTextItem(HSECTION section, string name, string value, bool editable = true, HITEM after = -1);
HITEM AddIntegerItem(HSECTION section, string name, int value, string format = "", bool editable = true, bool undefined = false, HITEM after = -1);
HITEM AddDoubleItem(HSECTION section, string name, double value, string format = "", bool editable = true, bool undefined = false, HITEM after = -1);
HITEM AddComboItem(HSECTION section, string name, const vector<string>& values, int cur, bool editable = true, bool undefined = false, HITEM after = -1);
HITEM AddBoolItem(HSECTION section, string name, bool value, bool editable = true, bool undefined = false, HITEM after = -1);
HITEM AddDateItem(HSECTION section, string name, COleDateTime value, string format = "", bool editable = true, bool undefined = false, HITEM after = -1);
HITEM AddDateTimeItem(HSECTION section, string name, COleDateTime value, string format = "", bool editable = true, bool undefined = false, HITEM after = -1);
HITEM AddFileItem(HSECTION section, string name, string value, string filter = "", bool editable = true, HITEM after = -1);
HITEM AddFolderItem(HSECTION section, string name, string value, string title = "", bool editable = true, HITEM after = -1);
HITEM AddColorItem(HSECTION section, string name, COLORREF value, bool editable = true, bool undefined = false, HITEM after = -1);
HITEM AddFontItem(HSECTION section, string name, LOGFONT value, bool editable = true, bool undefined = false, HITEM after = -1);
// contents
void ResetContents();
bool RemoveSection(HSECTION hs);
bool RemoveItem(HITEM item);
void ValidateChanges();
// status
int GetNumSections();
int GetSectionSize(HSECTION hs);
// get item value
bool GetItemValue(HITEM item, string& strValue) const;
bool GetItemValue(HITEM item, int& nValue) const;
bool GetItemValue(HITEM item, double& dValue) const;
bool GetItemValue(HITEM item, bool& bValue) const;
bool GetItemValue(HITEM item, COleDateTime& dtValue) const;
bool GetItemValue(HITEM item, COLORREF& clrValue) const;
bool GetItemValue(HITEM item, LOGFONT& lfValue) const;
// set item value
bool SetItemValue(HITEM item, const string strValue);
bool SetItemValue(HITEM item, const int nValue);
bool SetItemValue(HITEM item, const double nValue);
bool SetItemValue(HITEM item, const bool bValue);
bool SetItemValue(HITEM item, const COleDateTime dtValue);
bool SetItemValue(HITEM item, const COLORREF clrValue);
bool SetItemValue(HITEM item, const LOGFONT lfValue);
// for custom items
int GetTextMargin();
CFont* GetFontNormal();
CFont* GetFontBold();
// appearance stuff
void SetDisplayMode(EDisplayMode display_mode);
void ExpandAll(bool expand);
void ExpandSection(HSECTION hs, bool expand);
bool IsSectionCollapsed(HSECTION hs);
std::string GetItemText(HITEM hItem);
protected:
class CItem
{
public:
HITEM m_id;
bool m_editable;
bool m_undefined;
EItemType m_type;
string m_name;
vector<string> m_options;
int m_nValue;
double m_dValue;
string m_strValue;
bool m_bValue;
COleDateTime m_dtValue;
COLORREF m_clrValue;
LOGFONT m_lfValue;
ICustomItem* m_pCustom;
bool m_undefined_old;
int m_nValue_old;
double m_dValue_old;
string m_strValue_old;
bool m_bValue_old;
COleDateTime m_dtValue_old;
COLORREF m_clrValue_old;
LOGFONT m_lfValue_old;
CRect m_rcName;
CRect m_rcValue;
bool operator==(const HITEM& item) const;
bool operator==(const string& name) const;
void ValidateChanges();
};
// DOWNGRADE: Commented out to prevent "undefined identifier CPropertyGrid" error
//friend bool item_alpha_sort(vector<CPropertyGrid::CItem>::iterator it1, vector<CPropertyGrid::CItem>::iterator it2);
class CSection
{
public:
HSECTION m_id;
string m_title;
bool m_collapsed;
vector<CItem> m_items;
CRect m_rcSign;
CRect m_rcTitle;
bool operator==(const HSECTION& section) const;
};
vector<CSection> m_sections;
HSECTION m_focused_section;
HITEM m_focused_item;
EDisplayMode m_display_mode;
bool m_shade_titles;
bool m_draw_lines;
bool m_draw_gutter;
bool m_focus_disabled;
bool m_bold_modified;
bool m_bold_editables;
int m_gutter_width;
bool m_resizing_gutter;
CPoint m_ptLast;
CFont m_fntNormal;
CFont m_fntBold;
int m_line_height;
CRect m_rect_button;
CWnd* m_control;
bool m_button_pushed;
bool m_button_depressed;
bool m_value_clicked;
bool m_custom_tracking;
HSECTION m_section_id;
HITEM m_item_id;
string m_strTrue;
string m_strFalse;
string m_strOk;
string m_strCancel;
string m_strDate;
string m_strTime;
string m_strUndefined;
string m_strEmpty;
COLORREF m_clrText;
COLORREF m_clrTitle;
COLORREF m_clrBack;
COLORREF m_clrShade;
COLORREF m_clrFocus;
COLORREF m_clrHilite;
COLORREF m_clrEditable;
COLORREF m_clrDisabled;
protected:
DECLARE_MESSAGE_MAP()
// init control
void InitControl();
// drawing
void DrawItem(CDC& dc, int w, int x, int y, vector<CItem>::iterator& it);
// item management
CSection* FindSection(HSECTION hs) const;
CItem* FindItem(HITEM hi) const;
HITEM AddItem(HSECTION hs, EItemType type, string name, void* pValue, bool editable, bool undefined, HITEM after);
// scrolling stuff
CScrollBar m_scrollbar;
bool m_scroll_enabled;
int GetScrollOffset();
void RecalcLayout();
// editing
EEditMode GetEditMode(CItem& item);
void DeleteEditControl();
void EditFocusedItem();
// movement in list
void MoveForward(HSECTION& focused_section, HITEM& focused_item);
// keyboard
void FocusNextItem();
void FocusPrevItem();
protected:
virtual void PreSubclassWindow();
public:
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnDestroy();
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
afx_msg void OnPaint();
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnMouseMove(UINT nHitTest, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt);
afx_msg LRESULT OnComboSelChanged(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT OnEditChanged(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT OnDateChanged(WPARAM wParam, LPARAM lParam);
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg UINT OnGetDlgCode();
afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
};

View file

@ -0,0 +1,260 @@
// PropertyGridCombo.cpp : implementation file
//
#include "stdafx.h"
#include "PropertyGridCombo.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
static const int margin = 2;
// CPropertyGridCombo
IMPLEMENT_DYNCREATE(CPropertyGridCombo, CWnd)
CPropertyGridCombo::CPropertyGridCombo()
{
m_pFont = NULL;
m_nSelected = -1;
m_bTracking = false;
m_clrBack = GetSysColor(COLOR_WINDOW);
m_clrText = GetSysColor(COLOR_WINDOWTEXT);
m_clrFocus = GetSysColor(COLOR_HIGHLIGHT);
m_clrHilite = GetSysColor(COLOR_HIGHLIGHTTEXT);
}
CPropertyGridCombo::~CPropertyGridCombo()
{
}
//
// content management
//
void CPropertyGridCombo::AddString(string strItem)
{
m_Items.push_back(strItem);
}
void CPropertyGridCombo::SetCurSel(int nItem)
{
m_nSelected = nItem;
}
BEGIN_MESSAGE_MAP(CPropertyGridCombo, CWnd)
ON_WM_PAINT()
ON_WM_SHOWWINDOW()
ON_WM_LBUTTONDOWN()
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONUP()
ON_WM_DESTROY()
ON_WM_KILLFOCUS()
ON_WM_KEYDOWN()
ON_WM_GETDLGCODE()
END_MESSAGE_MAP()
//
// creation
//
BOOL CPropertyGridCombo::Create(DWORD dwStyle, CRect& rc, CWnd* pParent, int nId)
{
pParent->ClientToScreen(&rc);
BOOL ret = CWnd::CreateEx(0, AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW), "", dwStyle|WS_POPUP, rc, pParent->GetParent(), nId);
if (ret) SetOwner(pParent);
return ret;
}
void CPropertyGridCombo::SetFont(CFont* pFont, BOOL bRedraw)
{
m_pFont = pFont;
CWnd::SetFont(pFont, bRedraw);
}
void CPropertyGridCombo::SetColors(COLORREF clrBack, COLORREF clrText, COLORREF clrFocus, COLORREF clrHilite)
{
m_clrBack = clrBack;
m_clrText = clrText;
m_clrFocus = clrFocus;
m_clrHilite = clrHilite;
}
void CPropertyGridCombo::OnShowWindow(BOOL bShow, UINT nStatus)
{
if (bShow)
{
// get line height
CDC* pDC = GetDC();
int save = pDC->SaveDC();
pDC->SelectObject(m_pFont?m_pFont:GetFont());
m_line_height = pDC->GetTextExtent("Gg").cy + 2*margin;
pDC->RestoreDC(save);
ReleaseDC(pDC);
// size control
CRect rc;
GetWindowRect(&rc);
SetWindowPos(NULL, 0, 0, rc.Width(), int(m_Items.size())*m_line_height+2, SWP_NOOWNERZORDER|SWP_NOZORDER|SWP_NOMOVE);
SetFocus();
}
CWnd::OnShowWindow(bShow, nStatus);
}
void CPropertyGridCombo::OnDestroy()
{
CWnd::OnDestroy();
}
void CPropertyGridCombo::OnKillFocus(CWnd* pNewWnd)
{
CWnd::OnKillFocus(pNewWnd);
DestroyWindow();
}
//
// painting
//
void CPropertyGridCombo::OnPaint()
{
// check
if (m_nSelected<0) m_nSelected = 0;
if (m_nSelected>int(m_Items.size())-1) m_nSelected = int(m_Items.size())-1;
// client rect
CRect rc;
GetClientRect(&rc);
// brush
CBrush brush;
brush.CreateSolidBrush(m_clrBack);
// pen
CPen pen;
pen.CreatePen(PS_SOLID, 1, m_clrText);
// the dc
CPaintDC dc(this);
CBrush* pOldBrush = dc.SelectObject(&brush);
CPen* pOldPen = dc.SelectObject(&pen);
CFont* pOldFont = dc.SelectObject(m_pFont);
// draw
dc.SelectObject(&brush);
dc.SelectObject(&pen);
dc.Rectangle(rc);
// put items
int i = 0;
int y = 1;
dc.SelectObject(m_pFont);
dc.SetBkMode(TRANSPARENT);
for (vector<string>::iterator it = m_Items.begin(); it != m_Items.end(); ++it)
{
CRect rcItem(0, y, rc.Width(), y+m_line_height);
rcItem.DeflateRect(1,0,1,0);
if (i == m_nSelected)
{
dc.DrawFocusRect(rcItem);
dc.SetTextColor(m_clrHilite);
CRect rc = rcItem;
rc.DeflateRect(1,1);
dc.FillSolidRect(rc, m_clrFocus);
}
else
{
dc.SetTextColor(m_clrText);
}
// do it
rcItem.left += 2*margin;
dc.DrawText(it->c_str(), rcItem, DT_SINGLELINE|DT_VCENTER|DT_LEFT|DT_NOPREFIX);
y += m_line_height;
i++;
}
// clean up
dc.SelectObject(pOldFont);
dc.SelectObject(pOldPen);
dc.SelectObject(pOldBrush);
}
//
// mouse interaction
//
void CPropertyGridCombo::OnLButtonDown(UINT nFlags, CPoint point)
{
m_nSelected = point.y/m_line_height;
m_bTracking = true;
SetCapture();
Invalidate();
CWnd::OnLButtonDown(nFlags, point);
}
void CPropertyGridCombo::OnMouseMove(UINT nFlags, CPoint point)
{
if (m_bTracking)
{
m_nSelected = point.y/m_line_height;
Invalidate();
}
CWnd::OnMouseMove(nFlags, point);
}
void CPropertyGridCombo::OnLButtonUp(UINT nFlags, CPoint point)
{
if (m_bTracking)
{
ReleaseCapture();
m_bTracking = false;
Invalidate();
}
GetOwner()->SendMessage(WM_PG_COMBOSELCHANGED, m_nSelected, 0);
}
//
// keyboard interaction
//
UINT CPropertyGridCombo::OnGetDlgCode()
{
return DLGC_WANTALLKEYS;
}
void CPropertyGridCombo::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if (nChar == VK_LEFT || nChar == VK_UP)
{
m_nSelected = max(0, m_nSelected-1);
Invalidate();
}
else if (nChar == VK_RIGHT || nChar == VK_DOWN)
{
m_nSelected = min(int(m_Items.size())-1, m_nSelected+1);
Invalidate();
}
else if (nChar == VK_ESCAPE)
{
DestroyWindow();
return;
}
else if (nChar == VK_RETURN || nChar == VK_EXECUTE)
{
GetOwner()->SendMessage(WM_PG_COMBOSELCHANGED, m_nSelected, 0);
return;
}
CWnd::OnKeyDown(nChar, nRepCnt, nFlags);
}

View file

@ -0,0 +1,54 @@
#pragma once
#include <vector>
#include <string>
using namespace std;
// CPropertyGridCombo frame
#define WM_PG_COMBOSELCHANGED WM_USER+487
class CPropertyGridCombo : public CWnd
{
DECLARE_DYNCREATE(CPropertyGridCombo)
public:
CPropertyGridCombo();
virtual ~CPropertyGridCombo();
BOOL Create(DWORD dwStyle, CRect& rc, CWnd* pParent, int nId);
void SetFont(CFont* pFont, BOOL bRedraw = TRUE);
void SetColors(COLORREF clrBack, COLORREF clrText, COLORREF clrFocus, COLORREF clrHilite);
void AddString(string strItem);
void SetCurSel(int nItem);
protected:
vector<string> m_Items;
int m_nSelected;
CFont* m_pFont;
int m_line_height;
bool m_bTracking;
COLORREF m_clrBack;
COLORREF m_clrText;
COLORREF m_clrFocus;
COLORREF m_clrHilite;
protected:
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnPaint();
afx_msg void OnShowWindow(BOOL bShow, UINT nStatus);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnDestroy();
afx_msg void OnKillFocus(CWnd* pNewWnd);
afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg UINT OnGetDlgCode();
};

View file

@ -0,0 +1,82 @@
////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001, nabocorp
// All Rights Reserved
//
////////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "shlobj.h"
#include "PropertyGridDirectoryPicker.h"
#define BIF_NEWDIALOGSTYLE 0x0040
std::string CPropertyGridDirectoryPicker::m_strTitle = "Choose a directory";
CPropertyGridDirectoryPicker::CPropertyGridDirectoryPicker()
{
}
CPropertyGridDirectoryPicker::~CPropertyGridDirectoryPicker()
{
}
int CALLBACK CPropertyGridDirectoryPicker::BrowseCallbackProc(HWND hwnd,UINT uMsg,LPARAM lp, LPARAM pData)
{
switch(uMsg)
{
// If the dialog is being initialised
case BFFM_INITIALIZED:
{
// Send a SetSelection message on the passed directory
SendMessage(hwnd,BFFM_SETSELECTION,TRUE,pData);
break;
}
}
return 0;
}
bool CPropertyGridDirectoryPicker::PickDirectory(std::string &directory, HWND hwnd)
{
char pszBuffer[MAX_PATH];
pszBuffer[0] = '\0';
// Gets the Shell's default allocator
LPMALLOC pMalloc;
if (::SHGetMalloc(&pMalloc) == NOERROR)
{
BROWSEINFO bi;
LPITEMIDLIST pidl;
// Get help on BROWSEINFO struct
bi.hwndOwner = hwnd;
bi.pidlRoot = NULL;
bi.pszDisplayName = pszBuffer;
bi.lpszTitle = m_strTitle.c_str();
bi.ulFlags = BIF_RETURNFSANCESTORS | BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE ;
// The callback function initialises the dialog with the passed value
bi.lpfn = BrowseCallbackProc;
bi.lParam = LPARAM(directory.c_str());
// This next call issues the dialog box.
if ((pidl = ::SHBrowseForFolder(&bi)) != NULL)
{
// Get the full path into pszBuffer
::SHGetPathFromIDList(pidl, pszBuffer);
// Free the PIDL allocated by SHBrowseForFolder.
pMalloc->Free(pidl);
}
// Release the shell's allocator.
pMalloc->Release();
}
// get the result
if (strlen(pszBuffer) != 0)
{
directory = pszBuffer;
return TRUE;
}
return FALSE;
}

View file

@ -0,0 +1,28 @@
////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001, nabocorp
// All Rights Reserved
//
////////////////////////////////////////////////////////////////////////////////
#if !defined(AFX_DIRECTORYPICKER_H__CBBD1C74_A552_11D2_8ECA_00104BDC35E6__INCLUDED_)
#define AFX_DIRECTORYPICKER_H__CBBD1C74_A552_11D2_8ECA_00104BDC35E6__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
class CPropertyGridDirectoryPicker
{
public:
CPropertyGridDirectoryPicker();
virtual ~CPropertyGridDirectoryPicker();
static bool PickDirectory(std::string&, HWND hwnd);
static std::string m_strTitle;
protected:
static int CALLBACK BrowseCallbackProc(HWND hwnd,UINT uMsg,LPARAM lp, LPARAM pData);
};
#endif // !defined(AFX_DIRECTORYPICKER_H__CBBD1C74_A552_11D2_8ECA_00104BDC35E6__INCLUDED_)

View file

@ -0,0 +1,237 @@
// InPlaceEdit.cpp : implementation file
//
// Adapted by Chris Maunder <cmaunder@mail.com>
// Copyright (c) 1998-2002. All Rights Reserved.
//
// The code contained in this file is based on the original
// CPropertyGridInPlaceEdit from http://www.codeguru.com/listview/edit_subitems.shtml
//
// This code may be used in compiled form in any way you desire. This
// file may be redistributed unmodified by any means PROVIDING it is
// not sold for profit without the authors written consent, and
// providing that this notice and the authors name and all copyright
// notices remains intact.
//
// An email letting me know how you are using it would be nice as well.
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability for any damage/loss of business that
// this product may cause.
//
// For use with CGridCtrl v2.10+
//
// History:
// 10 May 1998 Uses GVN_ notifications instead of LVN_,
// Sends notification messages to the parent,
// instead of the parent's parent.
// 15 May 1998 There was a problem when editing with the in-place editor,
// there arises a general protection fault in user.exe, with a
// few qualifications:
// (1) This only happens with owner-drawn buttons;
// (2) This only happens in Win95
// (3) This only happens if the handler for the button does not
// create a new window (even an AfxMessageBox will avoid the
// crash)
// (4) This will not happen if Spy++ is running.
// PreTranslateMessage was added to route messages correctly.
// (Matt Weagle found and fixed this problem)
// 26 Jul 1998 Removed the ES_MULTILINE style - that fixed a few probs!
// 6 Aug 1998 Added nID to the constructor param list
// 6 Sep 1998 Space no longer clears selection when starting edit (Franco Bez)
// 10 Apr 1999 Enter, Tab and Esc key prob fixed (Koay Kah Hoe)
// Workaround for bizzare "shrinking window" problem in CE
//
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "TCHAR.h"
#include "PropertyGridInPlaceEdit.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CPropertyGridInPlaceEdit
CPropertyGridInPlaceEdit::CPropertyGridInPlaceEdit(CWnd* pParent, CRect& rect, DWORD dwStyle, UINT nID, string sInitText)
{
m_sInitText = sInitText.c_str();
m_bExitOnArrows = FALSE;
m_Rect = rect; // For bizarre CE bug.
DWORD dwEditStyle = /*WS_BORDER|*/WS_CHILD|/*WS_VISIBLE|*/ES_AUTOHSCROLL|dwStyle;
if (!Create(dwEditStyle, rect, pParent, nID))
return;
m_clrBack = GetSysColor(COLOR_WINDOW);
m_clrText = GetSysColor(COLOR_WINDOWTEXT);
m_Brush.CreateSolidBrush(m_clrBack);
SetFont(pParent->GetFont());
SetWindowText(m_sInitText);
SetFocus();
SetSel(0, -1);
SetSel(-1, 0);
}
CPropertyGridInPlaceEdit::~CPropertyGridInPlaceEdit()
{
}
void CPropertyGridInPlaceEdit::SetColors(COLORREF clrBack, COLORREF clrText)
{
m_clrBack = clrBack;
m_clrText = clrText;
m_Brush.DeleteObject();
m_Brush.CreateSolidBrush(m_clrBack);
}
BEGIN_MESSAGE_MAP(CPropertyGridInPlaceEdit, CEdit)
//{{AFX_MSG_MAP(CPropertyGridInPlaceEdit)
ON_WM_KILLFOCUS()
ON_WM_CHAR()
ON_WM_KEYDOWN()
ON_WM_GETDLGCODE()
ON_WM_CREATE()
ON_WM_CTLCOLOR_REFLECT( )
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
////////////////////////////////////////////////////////////////////////////
// CPropertyGridInPlaceEdit message handlers
// If an arrow key (or associated) is pressed, then exit if
// a) The Ctrl key was down, or
// b) m_bExitOnArrows == TRUE
void CPropertyGridInPlaceEdit::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if ((nChar == VK_PRIOR || nChar == VK_NEXT ||
nChar == VK_DOWN || nChar == VK_UP ||
nChar == VK_RIGHT || nChar == VK_LEFT) &&
(m_bExitOnArrows || GetKeyState(VK_CONTROL) < 0))
{
GetParent()->SetFocus();
return;
}
CEdit::OnKeyDown(nChar, nRepCnt, nFlags);
}
// As soon as this edit loses focus, kill it.
void CPropertyGridInPlaceEdit::OnKillFocus(CWnd* pNewWnd)
{
CEdit::OnKillFocus(pNewWnd);
EndEdit();
}
void CPropertyGridInPlaceEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if (nChar == VK_TAB || nChar == VK_RETURN)
{
GetParent()->SetFocus(); // This will destroy this window
return;
}
if (nChar == VK_ESCAPE)
{
CancelEdit();
return;
}
CEdit::OnChar(nChar, nRepCnt, nFlags);
//// Resize edit control if needed
//
//// Get text extent
//CString str;
//GetWindowText( str );
//// add some extra buffer
//str += _T(" ");
//
//CWindowDC dc(this);
//CFont *pFontDC = dc.SelectObject(GetFont());
//CSize size = dc.GetTextExtent( str );
//dc.SelectObject( pFontDC );
//
//// Get client rect
//CRect ParentRect;
//GetParent()->GetClientRect( &ParentRect );
//
//// Check whether control needs to be resized
//// and whether there is space to grow
//if (size.cx > m_Rect.Width())
//{
// if( size.cx + m_Rect.left < ParentRect.right )
// m_Rect.right = m_Rect.left + size.cx;
// else
// m_Rect.right = ParentRect.right;
// MoveWindow( &m_Rect );
//}
}
UINT CPropertyGridInPlaceEdit::OnGetDlgCode()
{
return DLGC_WANTALLKEYS;
}
////////////////////////////////////////////////////////////////////////////
// CPropertyGridInPlaceEdit overrides
// Stoopid win95 accelerator key problem workaround - Matt Weagle.
BOOL CPropertyGridInPlaceEdit::PreTranslateMessage(MSG* pMsg)
{
// Catch the Alt key so we don't choke if focus is going to an owner drawn button
if (pMsg->message == WM_SYSCHAR)
return TRUE;
return CEdit::PreTranslateMessage(pMsg);
}
////////////////////////////////////////////////////////////////////////////
// CPropertyGridInPlaceEdit implementation
void CPropertyGridInPlaceEdit::CancelEdit()
{
// restore previous text
if (IsWindow(GetSafeHwnd()))
{
SetWindowText(m_sInitText);
SendMessage(WM_CLOSE, 0, 0);
}
}
void CPropertyGridInPlaceEdit::EndEdit()
{
CString str;
// EFW - BUG FIX - Clicking on a grid scroll bar in a derived class
// that validates input can cause this to get called multiple times
// causing assertions because the edit control goes away the first time.
static BOOL bAlreadyEnding = FALSE;
if(bAlreadyEnding)
return;
bAlreadyEnding = TRUE;
GetWindowText(str);
CWnd* pOwner = GetOwner();
if (pOwner)
pOwner->SendMessage(WM_PG_ENDLABELEDIT, (WPARAM) LPCTSTR(str), NULL );
// Close this window (PostNcDestroy will delete this)
if (IsWindow(GetSafeHwnd()))
SendMessage(WM_CLOSE, 0, 0);
bAlreadyEnding = FALSE;
}
HBRUSH CPropertyGridInPlaceEdit::CtlColor ( CDC* pDC, UINT nCtlColor )
{
pDC->SetTextColor(m_clrText);
pDC->SetBkColor(m_clrBack);
return m_Brush;
}

View file

@ -0,0 +1,89 @@
//////////////////////////////////////////////////////////////////////
// InPlaceEdit.h : header file
//
// MFC Grid Control - inplace editing class
//
// Written by Chris Maunder <cmaunder@mail.com>
// Copyright (c) 1998-2002. All Rights Reserved.
//
// This code may be used in compiled form in any way you desire. This
// file may be redistributed unmodified by any means PROVIDING it is
// not sold for profit without the authors written consent, and
// providing that this notice and the authors name and all copyright
// notices remains intact.
//
// An email letting me know how you are using it would be nice as well.
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability for any damage/loss of business that
// this product may cause.
//
// For use with CGridCtrl v2.10+
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_GRIDINPLACEEDIT_H__ECD42821_16DF_11D1_992F_895E185F9C72__INCLUDED_)
#define AFX_GRIDINPLACEEDIT_H__ECD42821_16DF_11D1_992F_895E185F9C72__INCLUDED_
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
#include <string>
using namespace std;
#define WM_PG_ENDLABELEDIT WM_USER+488
class CPropertyGridInPlaceEdit : public CEdit
{
// Construction
public:
CPropertyGridInPlaceEdit(CWnd* pParent, CRect& rect, DWORD dwStyle, UINT nID, string sInitText);
void SetColors(COLORREF clrBack, COLORREF clrText);
// Attributes
public:
// Operations
public:
void CancelEdit();
void EndEdit();
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CPropertyGridInPlaceEdit)
public:
virtual BOOL PreTranslateMessage(MSG* pMsg);
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CPropertyGridInPlaceEdit();
// Generated message map functions
protected:
//{{AFX_MSG(CPropertyGridInPlaceEdit)
afx_msg void OnKillFocus(CWnd* pNewWnd);
afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg UINT OnGetDlgCode();
afx_msg HBRUSH CtlColor ( CDC* pDC, UINT nCtlColor );
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
private:
CString m_sInitText;
BOOL m_bExitOnArrows;
CRect m_Rect;
COLORREF m_clrBack;
COLORREF m_clrText;
CBrush m_Brush;
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_GRIDINPLACEEDIT_H__ECD42821_16DF_11D1_992F_895E185F9C72__INCLUDED_)

View file

@ -0,0 +1,67 @@
// PropertyGridMonthCalCtrl.cpp : implementation file
//
#include "stdafx.h"
#include "PropertyGridMonthCalCtrl.h"
// CPropertyGridMonthCalCtrl
// DOWNGRADE: Commented out to prevent link error where CRuntimeStatic for CMonthCalCtrl is unresolved
//IMPLEMENT_DYNAMIC(CPropertyGridMonthCalCtrl, CMonthCalCtrl)
CPropertyGridMonthCalCtrl::CPropertyGridMonthCalCtrl()
{
}
CPropertyGridMonthCalCtrl::~CPropertyGridMonthCalCtrl()
{
}
BEGIN_MESSAGE_MAP(CPropertyGridMonthCalCtrl, CMonthCalCtrl)
ON_WM_KILLFOCUS()
ON_NOTIFY_REFLECT(MCN_SELECT, OnMcnSelect)
ON_WM_GETDLGCODE()
ON_WM_KEYDOWN()
END_MESSAGE_MAP()
// CPropertyGridMonthCalCtrl message handlers
void CPropertyGridMonthCalCtrl::OnKillFocus(CWnd* pNewWnd)
{
CMonthCalCtrl::OnKillFocus(pNewWnd);
CWnd* pParent = pNewWnd ? pNewWnd->GetParent() : NULL;
if (pParent != this)
DestroyWindow();
}
void CPropertyGridMonthCalCtrl::OnMcnSelect(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMSELCHANGE pSelChange = reinterpret_cast<LPNMSELCHANGE>(pNMHDR);
GetOwner()->SendMessage(WM_PG_DATESELCHANGED);
*pResult = 0;
}
UINT CPropertyGridMonthCalCtrl::OnGetDlgCode()
{
return DLGC_WANTALLKEYS;
}
void CPropertyGridMonthCalCtrl::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if (nChar == VK_ESCAPE)
{
DestroyWindow();
return;
}
else if (nChar == VK_RETURN || nChar == VK_EXECUTE)
{
GetOwner()->SendMessage(WM_PG_DATESELCHANGED);
return;
}
CMonthCalCtrl::OnKeyDown(nChar, nRepCnt, nFlags);
}

View file

@ -0,0 +1,25 @@
#pragma once
#define WM_PG_DATESELCHANGED WM_USER+489
// CPropertyGridMonthCalCtrl
class CPropertyGridMonthCalCtrl : public CMonthCalCtrl
{
// DOWNGRADE: Commented out to prevent link error where CRuntimeStatic for CMonthCalCtrl is unresolved
//DECLARE_DYNAMIC(CPropertyGridMonthCalCtrl)
public:
CPropertyGridMonthCalCtrl();
virtual ~CPropertyGridMonthCalCtrl();
protected:
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnKillFocus(CWnd* pNewWnd);
afx_msg void OnMcnSelect(NMHDR *pNMHDR, LRESULT *pResult);
afx_msg UINT OnGetDlgCode();
afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
};

View file

@ -0,0 +1,5 @@
# Fully customizable PropertyGrid for MFC 4.2
Original project by Nicolas Bonamy at CodeProject: https://www.codeproject.com/Articles/18933/A-fully-customizable-PropertyGrid
This is a port of that project to CMake with minor changes so it can compile with Visual C++ 6.0.

View file

@ -0,0 +1,7 @@
// stdafx.cpp : source file that includes just the standard includes
// PropGrid.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"

29
ext/PropertyGrid/stdafx.h Normal file
View file

@ -0,0 +1,29 @@
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#if !defined(AFX_STDAFX_H__8E104244_6D3A_49FB_B014_338D08085215__INCLUDED_)
#define AFX_STDAFX_H__8E104244_6D3A_49FB_B014_338D08085215__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
#include <afxwin.h> // MFC core and standard components
#include <afxext.h> // MFC extensions
#include <afxdisp.h> // MFC Automation classes
#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h> // MFC support for Windows Common Controls
#endif // _AFX_NO_AFXCMN_SUPPORT
#include <assert.h>
#include <string>
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_STDAFX_H__8E104244_6D3A_49FB_B014_338D08085215__INCLUDED_)

View file

@ -0,0 +1,23 @@
add_executable(PropGrid WIN32
CustomTreeCtrl.cpp
CustomTreeCtrl.h
GradientItem.cpp
GradientItem.h
PropGrid.cpp
PropGrid.h
PropGrid.rc
PropGridDlg.cpp
PropGridDlg.h
RectEditDlg.cpp
RectEditDlg.h
RectItem.cpp
RectItem.h
resource.h
SerialItem.cpp
SerialItem.h
TreeItem.cpp
TreeItem.h
)
target_include_directories(PropGrid PRIVATE "..")
target_link_libraries(PropGrid PRIVATE PropertyGrid)

View file

@ -0,0 +1,88 @@
// CustomTreeCtrl.cpp : implementation file
//
#include "stdafx.h"
#include "PropGrid.h"
#include "CustomTreeCtrl.h"
#include "TreeItem.h"
#include ".\customtreectrl.h"
// CCustomTreeCtrl
IMPLEMENT_DYNAMIC(CCustomTreeCtrl, CTreeCtrl)
CCustomTreeCtrl::CCustomTreeCtrl()
{
}
CCustomTreeCtrl::~CCustomTreeCtrl()
{
}
BEGIN_MESSAGE_MAP(CCustomTreeCtrl, CTreeCtrl)
ON_WM_GETDLGCODE()
ON_WM_KILLFOCUS()
ON_NOTIFY_REFLECT(TVN_SELCHANGED, OnTvnSelchanged)
ON_WM_KEYDOWN()
END_MESSAGE_MAP()
// CCustomTreeCtrl message handlers
UINT CCustomTreeCtrl::OnGetDlgCode()
{
return DLGC_WANTALLKEYS;
}
void CCustomTreeCtrl::OnKillFocus(CWnd* pNewWnd)
{
CTreeCtrl::OnKillFocus(pNewWnd);
DestroyWindow();
}
void CCustomTreeCtrl::OnTvnSelchanged(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
if (pNMTreeView->action == TVC_BYMOUSE)
Validate();
*pResult = 0;
}
void CCustomTreeCtrl::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if (nChar == VK_ESCAPE)
{
DestroyWindow();
return;
}
else if (nChar == VK_RETURN || nChar == VK_EXECUTE)
{
Validate();
return;
}
CTreeCtrl::OnKeyDown(nChar, nRepCnt, nFlags);
}
void CCustomTreeCtrl::Validate()
{
if (GetSafeHwnd())
{
HTREEITEM hItem = GetSelectedItem();
if (hItem && !ItemHasChildren(hItem))
{
CString strText = GetItemText(hItem);
m_item->SetValue(LPCTSTR(strText));
DestroyWindow();
}
}
}
void CCustomTreeCtrl::PostNcDestroy()
{
CTreeCtrl::PostNcDestroy();
delete this;
}

View file

@ -0,0 +1,32 @@
#pragma once
#include "..\PropertyGrid.h"
class CTreeItem;
// CCustomTreeCtrl
class CCustomTreeCtrl : public CTreeCtrl
{
DECLARE_DYNAMIC(CCustomTreeCtrl)
public:
CCustomTreeCtrl();
virtual ~CCustomTreeCtrl();
CTreeItem* m_item;
protected:
DECLARE_MESSAGE_MAP()
void Validate();
public:
afx_msg UINT OnGetDlgCode();
afx_msg void OnKillFocus(CWnd* pNewWnd);
afx_msg void OnTvnSelchanged(NMHDR *pNMHDR, LRESULT *pResult);
afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
protected:
virtual void PostNcDestroy();
};

View file

@ -0,0 +1,108 @@
#include "StdAfx.h"
#include "GradientItem.h"
CGradientItem::CGradientItem(void)
{
m_clrLeft = RGB(0,0,0);
m_clrRight = RGB(0,255,0);
m_nButtonPushed = 0;
}
CPropertyGrid::EEditMode CGradientItem::GetEditMode()
{
return CPropertyGrid::EM_CUSTOM;
}
void CGradientItem::DrawItem(CDC& dc, CRect rc, bool focused)
{
CRect rect = rc;
rect.DeflateRect(focused?rc.Height()+2:2, 2);
CBrush brush;
brush.CreateSolidBrush(GetSysColor(COLOR_WINDOWTEXT));
dc.FrameRect(rect, &brush);
rect.DeflateRect(1,1);
TRIVERTEX vert[2] ;
GRADIENT_RECT gRect;
vert [0] .x = rect.left;
vert [0] .y = rect.top;
vert [0] .Red = GetRValue(m_clrLeft)*256;
vert [0] .Green = GetGValue(m_clrLeft)*256;
vert [0] .Blue = GetBValue(m_clrLeft)*256;
vert [0] .Alpha = 0x0000;
vert [1] .x = rect.right;
vert [1] .y = rect.bottom;
vert [1] .Red = GetRValue(m_clrRight)*256;
vert [1] .Green = GetGValue(m_clrRight)*256;
vert [1] .Blue = GetBValue(m_clrRight)*256;
vert [1] .Alpha = 0x0000;
gRect.UpperLeft = 0;
gRect.LowerRight = 1;
// DOWNGRADE: Commented out because MFC 4.2 doesn't have GradientFill
//dc.GradientFill(vert,2,&gRect,1,GRADIENT_FILL_RECT_H);
if (focused)
{
// for propert clean up
CFont* pOldFont = dc.SelectObject(m_pGrid->GetFontBold());
// the left button
CRect rc1 = rc;
rc1.right = rc1.left + rc1.Height();
dc.DrawFrameControl(rc1, DFC_BUTTON, DFCS_BUTTONPUSH|(m_nButtonPushed==1?DFCS_PUSHED:0));
dc.SelectObject(m_pGrid->GetFontBold());
dc.DrawText("...", rc1, DT_CENTER|DT_SINGLELINE|DT_VCENTER|DT_NOPREFIX);
// the right button
CRect rc2 = rc;
rc2.left = rc2.right - rc2.Height();
dc.DrawFrameControl(rc2, DFC_BUTTON, DFCS_BUTTONPUSH|(m_nButtonPushed==2?DFCS_PUSHED:0));
dc.SelectObject(m_pGrid->GetFontBold());
dc.DrawText("...", rc2, DT_CENTER|DT_SINGLELINE|DT_VCENTER|DT_NOPREFIX);
// clean up
dc.SelectObject(pOldFont);
}
}
bool CGradientItem::OnLButtonDown(CRect rc, CPoint pt)
{
m_nButtonPushed = 0;
if (rc.PtInRect(pt))
{
if (pt.x<=rc.left+rc.Height())
{
m_nButtonPushed = 1;
return true;
}
if (pt.x>=rc.right-rc.Height())
{
m_nButtonPushed = 2;
return true;
}
}
return false;
}
void CGradientItem::OnMouseMove(CRect rc, CPoint pt)
{
OnLButtonDown(rc, pt);
}
void CGradientItem::OnLButtonUp(CRect rc, CPoint pt)
{
COLORREF& clr = (m_nButtonPushed==1) ? m_clrLeft : m_clrRight;
m_nButtonPushed = 0;
CColorDialog dlg(clr, 0, m_pGrid);
if (dlg.DoModal() == IDOK)
{
clr = dlg.GetColor();
m_pGrid->Invalidate();
}
}

View file

@ -0,0 +1,21 @@
#pragma once
#include "..\CustomItem.h"
class CGradientItem :
public ICustomItem
{
public:
CGradientItem(void);
public:
virtual CPropertyGrid::EEditMode GetEditMode();
virtual void DrawItem(CDC& dc, CRect rc, bool focused);
virtual bool OnLButtonDown(CRect rc, CPoint pt);
virtual void OnMouseMove(CRect rc, CPoint pt);
virtual void OnLButtonUp(CRect rc, CPoint pt);
protected:
COLORREF m_clrLeft;
COLORREF m_clrRight;
int m_nButtonPushed; //0: none, 1: left, 2:right
};

View file

@ -0,0 +1,71 @@
// PropGrid.cpp : Defines the class behaviors for the application.
//
#include "stdafx.h"
#include "PropGrid.h"
#include "PropGridDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CPropGridApp
BEGIN_MESSAGE_MAP(CPropGridApp, CWinApp)
ON_COMMAND(ID_HELP, CWinApp::OnHelp)
END_MESSAGE_MAP()
// CPropGridApp construction
CPropGridApp::CPropGridApp()
{
// TODO: add construction code here,
// Place all significant initialization in InitInstance
}
// The one and only CPropGridApp object
CPropGridApp theApp;
// CPropGridApp initialization
BOOL CPropGridApp::InitInstance()
{
// InitCommonControls() is required on Windows XP if an application
// manifest specifies use of ComCtl32.dll version 6 or later to enable
// visual styles. Otherwise, any window creation will fail.
InitCommonControls();
CWinApp::InitInstance();
// Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need
// Change the registry key under which our settings are stored
// TODO: You should modify this string to be something appropriate
// such as the name of your company or organization
SetRegistryKey(_T("Local AppWizard-Generated Applications"));
CPropGridDlg dlg;
m_pMainWnd = &dlg;
INT_PTR nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
// TODO: Place code here to handle when the dialog is
// dismissed with OK
}
else if (nResponse == IDCANCEL)
{
// TODO: Place code here to handle when the dialog is
// dismissed with Cancel
}
// Since the dialog has been closed, return FALSE so that we exit the
// application, rather than start the application's message pump.
return FALSE;
}

View file

@ -0,0 +1,31 @@
// PropGrid.h : main header file for the PROJECT_NAME application
//
#pragma once
#ifndef __AFXWIN_H__
#error include 'stdafx.h' before including this file for PCH
#endif
#include "resource.h" // main symbols
// CPropGridApp:
// See PropGrid.cpp for the implementation of this class
//
class CPropGridApp : public CWinApp
{
public:
CPropGridApp();
// Overrides
public:
virtual BOOL InitInstance();
// Implementation
DECLARE_MESSAGE_MAP()
};
extern CPropGridApp theApp;

View file

@ -0,0 +1,219 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_PROPGRID_DIALOG DIALOGEX 0, 0, 358, 188
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE |
WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_APPWINDOW
CAPTION "PropGrid"
FONT 8, "MS Shell Dlg", 400, 0, 0x0
BEGIN
CONTROL "Categorized",IDC_CATEGORIZED,"Button",
BS_AUTORADIOBUTTON | WS_GROUP,272,22,55,10
CONTROL "Alphabetical",IDC_ALPHABETICAL,"Button",
BS_AUTORADIOBUTTON,272,35,55,10
CONTROL "No Sort",IDC_NOSORT,"Button",BS_AUTORADIOBUTTON,272,48,
55,10
CONTROL "Custom colors",IDC_CUSTOM_COLORS,"Button",
BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,256,72,95,10
PUSHBUTTON "Collapse",IDC_COLLAPSE_ALL,256,85,45,14
PUSHBUTTON "Expand",IDC_EXPAND_ALL,306,85,45,14
DEFPUSHBUTTON "OK",IDOK,301,144,50,16
CONTROL "",IDC_GRID,"Static",SS_BLACKFRAME | SS_NOTIFY,7,7,239,
174,WS_EX_TRANSPARENT | WS_EX_CLIENTEDGE
GROUPBOX "Display Mode",IDC_STATIC,256,7,95,63
PUSHBUTTON "Cancel",IDCANCEL,301,165,50,16
END
IDD_RECT_EDIT DIALOGEX 0, 0, 123, 114
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION |
WS_SYSMENU
CAPTION "Rectangle"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "OK",IDOK,9,92,50,14
PUSHBUTTON "Cancel",IDCANCEL,63,92,50,14
RTEXT "Left",IDC_STATIC,20,18,24,8
RTEXT "Top",IDC_STATIC,20,33,24,8
RTEXT "Right",IDC_STATIC,20,48,24,8
RTEXT "Bottom",IDC_STATIC,20,63,24,8
EDITTEXT IDC_LEFT,52,15,53,14,ES_AUTOHSCROLL
EDITTEXT IDC_TOP,52,30,53,14,ES_AUTOHSCROLL
EDITTEXT IDC_RIGHT,52,45,53,14,ES_AUTOHSCROLL
EDITTEXT IDC_BOTTOM,52,60,53,14,ES_AUTOHSCROLL
GROUPBOX "",IDC_STATIC,7,3,109,80
END
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,0,1
PRODUCTVERSION 1,0,0,1
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x4L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904e4"
BEGIN
VALUE "CompanyName", "TODO: <Company name>"
VALUE "FileDescription", "TODO: <File description>"
VALUE "FileVersion", "1.0.0.1"
VALUE "InternalName", "PropGrid.exe"
VALUE "LegalCopyright", "TODO: (c) <Company name>. All rights reserved."
VALUE "OriginalFilename", "PropGrid.exe"
VALUE "ProductName", "TODO: <Product name>"
VALUE "ProductVersion", "1.0.0.1"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1252
END
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
IDD_PROPGRID_DIALOG, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 351
TOPMARGIN, 7
BOTTOMMARGIN, 181
END
IDD_RECT_EDIT, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 116
TOPMARGIN, 7
BOTTOMMARGIN, 107
END
END
#endif // APSTUDIO_INVOKED
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// French (France) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_FRA)
#ifdef _WIN32
LANGUAGE LANG_FRENCH, SUBLANG_FRENCH
#pragma code_page(1252)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"#define _AFX_NO_SPLITTER_RESOURCES\r\n"
"#define _AFX_NO_OLE_RESOURCES\r\n"
"#define _AFX_NO_TRACKER_RESOURCES\r\n"
"#define _AFX_NO_PROPERTY_RESOURCES\r\n"
"\r\n"
"#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n"
"LANGUAGE 9, 1\r\n"
"#pragma code_page(1252)\r\n"
"#include ""res\\PropGrid.rc2"" // non-Microsoft Visual C++ edited resources\r\n"
"#include ""afxres.rc"" // Standard components\r\n"
"#endif\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDR_MAINFRAME ICON "res\\PropGrid.ico"
#endif // French (France) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
#define _AFX_NO_SPLITTER_RESOURCES
#define _AFX_NO_OLE_RESOURCES
#define _AFX_NO_TRACKER_RESOURCES
#define _AFX_NO_PROPERTY_RESOURCES
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
LANGUAGE 9, 1
#pragma code_page(1252)
#include "res\PropGrid.rc2" // non-Microsoft Visual C++ edited resources
#include "afxres.rc" // Standard components
#endif
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View file

@ -0,0 +1,238 @@
// PropGridDlg.cpp : implementation file
//
#include "stdafx.h"
#include "PropGrid.h"
#include "PropGridDlg.h"
#include ".\propgriddlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CPropGridDlg dialog
CPropGridDlg::CPropGridDlg(CWnd* pParent /*=NULL*/)
: CDialog(CPropGridDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CPropGridDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_GRID, m_ctrlGrid);
}
BEGIN_MESSAGE_MAP(CPropGridDlg, CDialog)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDOK, OnBnClickedOk)
ON_MESSAGE(WM_PG_ITEMCHANGED, OnItemChanged)
ON_BN_CLICKED(IDC_COLLAPSE_ALL, OnBnClickedCollapseAll)
ON_BN_CLICKED(IDC_EXPAND_ALL, OnBnClickedExpandAll)
ON_BN_CLICKED(IDC_CUSTOM_COLORS, OnBnClickedCustomColors)
ON_BN_CLICKED(IDC_CATEGORIZED, OnBnClickedCategorized)
ON_BN_CLICKED(IDC_ALPHABETICAL, OnBnClickedAlphabetical)
ON_BN_CLICKED(IDC_NOSORT, OnBnClickedNosort)
END_MESSAGE_MAP()
// CPropGridDlg message handlers
BOOL CPropGridDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// basic items
HSECTION hs = m_ctrlGrid.AddSection("Basic Items");
m_ctrlGrid.AddStringItem(hs, "String", "A single line string item");
m_ctrlGrid.AddTextItem(hs, "Text", "A multi line text item.\r\nSecond line...");
m_ctrlGrid.AddStringItem(hs, "Disabled item", "A disabled item", false);
m_ctrlGrid.AddIntegerItem(hs, "Integer", 10);
m_ctrlGrid.AddIntegerItem(hs, "Formatted Integer", 8, "%d inches");
m_ctrlGrid.AddDoubleItem(hs, "Double", 7.33);
m_ctrlGrid.AddDoubleItem(hs, "Formatted Double", 10.25, "%gmm");
m_ctrlGrid.AddBoolItem(hs, "Boolean", true);
// custom items
hs = m_ctrlGrid.AddSection("Custom Items");
m_ctrlGrid.AddCustomItem(hs, "Custom In-place Edit", &m_item_serial);
m_ctrlGrid.AddCustomItem(hs, "Custom Modal Edit", &m_item_rect);
m_ctrlGrid.AddCustomItem(hs, "Ccustom Dropdown Edit", &m_item_tree);
m_ctrlGrid.AddCustomItem(hs, "Full Custom Edit", &m_item_gradient);
// more items inserted before the custom ones
hs = m_ctrlGrid.AddSection("More Items", true, hs);
// a combo
vector<string> v;
v.push_back("English");
v.push_back("French");
v.push_back("German");
v.push_back("Spanish");
m_ctrlGrid.AddComboItem(hs, "Combo", v, 2, true);
// some "simple"
m_ctrlGrid.AddDateItem(hs, "Date", COleDateTime::GetCurrentTime());
m_ctrlGrid.AddDateItem(hs, "Formatted Date", COleDateTime::GetCurrentTime(), "%A, %d %B %Y");
m_ctrlGrid.AddDateTimeItem(hs, "Date Time", COleDateTime::GetCurrentTime());
m_ctrlGrid.AddColorItem(hs, "Color", RGB(255,156,12));
m_ctrlGrid.AddFileItem(hs, "File", "C:\\AUTOEXEC.BAT", "All Files (*.*)|*.*||");
m_ctrlGrid.AddFolderItem(hs, "Folder", "C:\\", "Select a folder");
// a font
LOGFONT lf;
CFont font;
font.CreatePointFont(80, "Tahoma");
font.GetLogFont(&lf);
m_ctrlGrid.AddFontItem(hs, "Font", lf, true);
// customization
hs = m_ctrlGrid.AddSection("Grid customization");
m_hItemShade = m_ctrlGrid.AddBoolItem(hs, "Shade titles", m_ctrlGrid.GetShadeTitles());
m_hItemLines = m_ctrlGrid.AddBoolItem(hs, "Draw lines", m_ctrlGrid.GetDrawLines());
m_hItemGutter = m_ctrlGrid.AddBoolItem(hs, "Draw gutter", m_ctrlGrid.GetDrawGutter());
m_hItemFocusDis = m_ctrlGrid.AddBoolItem(hs, "Focus disabled items", m_ctrlGrid.GetFocusDisabled());
// stuff
m_ctrlGrid.SetOkCancelStrings("OK", "Annuler");
m_ctrlGrid.SetDateTimeStrings("Date", "Heure");
//
((CButton*)GetDlgItem(IDC_CATEGORIZED))->SetCheck(1);
return TRUE; // return TRUE unless you set the focus to a control
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CPropGridDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this function to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CPropGridDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void CPropGridDlg::OnBnClickedOk()
{
//string strValue;
//if (m_ctrlGrid.GetItemValue(m_hItem, strValue))
// AfxMessageBox(strValue.c_str());
OnOK();
}
LRESULT CPropGridDlg::OnItemChanged(WPARAM wParam, LPARAM lParam)
{
if (wParam == m_hItemLines)
{
bool draw_lines;
m_ctrlGrid.GetItemValue(m_hItemLines, draw_lines);
m_ctrlGrid.SetDrawLines(draw_lines);
}
else if (wParam == m_hItemShade)
{
bool shade_titles;
m_ctrlGrid.GetItemValue(m_hItemShade, shade_titles);
m_ctrlGrid.SetShadeTitles(shade_titles);
}
else if (wParam == m_hItemGutter)
{
bool draw_gutter;
m_ctrlGrid.GetItemValue(m_hItemGutter, draw_gutter);
m_ctrlGrid.SetDrawGutter(draw_gutter);
}
else if (wParam == m_hItemFocusDis)
{
bool focus_disabled;
m_ctrlGrid.GetItemValue(m_hItemFocusDis, focus_disabled);
m_ctrlGrid.SetFocusDisabled(focus_disabled);
}
return 0;
}
void CPropGridDlg::OnBnClickedCollapseAll()
{
m_ctrlGrid.ExpandAll(false);
}
void CPropGridDlg::OnBnClickedExpandAll()
{
m_ctrlGrid.ExpandAll(true);
}
void CPropGridDlg::OnBnClickedCustomColors()
{
CButton* pBtn = (CButton*) GetDlgItem(IDC_CUSTOM_COLORS);
if (pBtn->GetCheck() == 0)
{
m_ctrlGrid.SetBackColor(GetSysColor(COLOR_WINDOW));
m_ctrlGrid.SetShadeColor(GetSysColor(COLOR_3DFACE));
m_ctrlGrid.SetTextColor(GetSysColor(COLOR_WINDOWTEXT));
m_ctrlGrid.SetTitleColor(GetSysColor(COLOR_WINDOWTEXT));
}
else
{
m_ctrlGrid.SetBackColor(RGB(0xFF, 0xFF, 0xE0));
m_ctrlGrid.SetShadeColor(RGB(0,187,94));
m_ctrlGrid.SetTextColor(RGB(0,0,192));
m_ctrlGrid.SetTitleColor(RGB(255,255,255));
}
}
void CPropGridDlg::OnBnClickedCategorized()
{
m_ctrlGrid.SetDisplayMode(CPropertyGrid::DM_CATEGORIZED);
GetDlgItem(IDC_EXPAND_ALL)->EnableWindow(TRUE);
GetDlgItem(IDC_COLLAPSE_ALL)->EnableWindow(TRUE);
}
void CPropGridDlg::OnBnClickedAlphabetical()
{
m_ctrlGrid.SetDisplayMode(CPropertyGrid::DM_ALPHABETICAL);
GetDlgItem(IDC_EXPAND_ALL)->EnableWindow(FALSE);
GetDlgItem(IDC_COLLAPSE_ALL)->EnableWindow(FALSE);
}
void CPropGridDlg::OnBnClickedNosort()
{
m_ctrlGrid.SetDisplayMode(CPropertyGrid::DM_NOSORT);
GetDlgItem(IDC_EXPAND_ALL)->EnableWindow(FALSE);
GetDlgItem(IDC_COLLAPSE_ALL)->EnableWindow(FALSE);
}

View file

@ -0,0 +1,54 @@
// PropGridDlg.h : header file
//
#pragma once
#include "..\PropertyGrid.h"
#include "GradientItem.h"
#include "SerialItem.h"
#include "RectItem.h"
#include "TreeItem.h"
// CPropGridDlg dialog
class CPropGridDlg : public CDialog
{
// Construction
public:
CPropGridDlg(CWnd* pParent = NULL); // standard constructor
// Dialog Data
enum { IDD = IDD_PROPGRID_DIALOG };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
protected:
CGradientItem m_item_gradient;
CSerialItem m_item_serial;
CRectItem m_item_rect;
CTreeItem m_item_tree;
// Implementation
protected:
HICON m_hIcon;
HITEM m_hItemLines;
HITEM m_hItemShade;
HITEM m_hItemGutter;
HITEM m_hItemFocusDis;
// Generated message map functions
virtual BOOL OnInitDialog();
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
public:
CPropertyGrid m_ctrlGrid;
afx_msg LRESULT OnItemChanged(WPARAM, LPARAM);
afx_msg void OnBnClickedOk();
afx_msg void OnBnClickedCollapseAll();
afx_msg void OnBnClickedExpandAll();
afx_msg void OnBnClickedCustomColors();
afx_msg void OnBnClickedCategorized();
afx_msg void OnBnClickedAlphabetical();
afx_msg void OnBnClickedNosort();
};

View file

@ -0,0 +1,43 @@
// RectEditDlg.cpp : implementation file
//
#include "stdafx.h"
#include "PropGrid.h"
#include "RectEditDlg.h"
// CRectEditDlg dialog
IMPLEMENT_DYNAMIC(CRectEditDlg, CDialog)
CRectEditDlg::CRectEditDlg(CWnd* pParent /*=NULL*/)
: CDialog(CRectEditDlg::IDD, pParent)
, m_left(10)
, m_top(10)
, m_right(10)
, m_bottom(10)
{
}
CRectEditDlg::~CRectEditDlg()
{
}
void CRectEditDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Text(pDX, IDC_LEFT, m_left);
DDV_MinMaxInt(pDX, m_left, 1, 1000);
DDX_Text(pDX, IDC_TOP, m_top);
DDV_MinMaxInt(pDX, m_top, 1, 1000);
DDX_Text(pDX, IDC_RIGHT, m_right);
DDV_MinMaxInt(pDX, m_right, 1, 1000);
DDX_Text(pDX, IDC_BOTTOM, m_bottom);
DDV_MinMaxInt(pDX, m_bottom, 1, 1000);
}
BEGIN_MESSAGE_MAP(CRectEditDlg, CDialog)
END_MESSAGE_MAP()
// CRectEditDlg message handlers

View file

@ -0,0 +1,26 @@
#pragma once
#include "resource.h"
// CRectEditDlg dialog
class CRectEditDlg : public CDialog
{
DECLARE_DYNAMIC(CRectEditDlg)
public:
CRectEditDlg(CWnd* pParent = NULL); // standard constructor
virtual ~CRectEditDlg();
// Dialog Data
enum { IDD = IDD_RECT_EDIT };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
DECLARE_MESSAGE_MAP()
public:
int m_left;
int m_top;
int m_right;
int m_bottom;
};

View file

@ -0,0 +1,46 @@
#include "StdAfx.h"
#include "RectItem.h"
#include "RectEditDlg.h"
CRectItem::CRectItem(void)
{
m_left = 20;
m_top = 20;
m_right = 100;
m_bottom = 100;
}
CRectItem::~CRectItem(void)
{
}
CPropertyGrid::EEditMode CRectItem::GetEditMode()
{
return CPropertyGrid::EM_MODAL;
}
void CRectItem::DrawItem(CDC& dc, CRect rc, bool focused)
{
CString str;
str.Format("%d; %d; %d; %d", m_left, m_top, m_right, m_bottom);
rc.left += m_pGrid->GetTextMargin();
dc.DrawText(str, rc, DT_SINGLELINE|DT_LEFT|DT_VCENTER|DT_END_ELLIPSIS|DT_NOPREFIX);
}
bool CRectItem::OnEditItem()
{
CRectEditDlg dlg(m_pGrid);
dlg.m_left = m_left;
dlg.m_top = m_top;
dlg.m_right = m_right;
dlg.m_bottom = m_bottom;
if (dlg.DoModal() == IDOK)
{
m_left = dlg.m_left;
m_top = dlg.m_top;
m_right = dlg.m_right;
m_bottom = dlg.m_bottom;
return true;
}
return false;
}

View file

@ -0,0 +1,19 @@
#pragma once
#include "..\CustomItem.h"
class CRectItem : public ICustomItem
{
public:
CRectItem(void);
~CRectItem(void);
virtual CPropertyGrid::EEditMode GetEditMode();
virtual void DrawItem(CDC& dc, CRect rc, bool focused);
virtual bool OnEditItem();
protected:
int m_left;
int m_top;
int m_right;
int m_bottom;
};

View file

@ -0,0 +1,44 @@
#include "StdAfx.h"
#include ".\serialitem.h"
CSerialItem::CSerialItem(void)
{
m_serial = "12348765";
}
CSerialItem::~CSerialItem(void)
{
}
CPropertyGrid::EEditMode CSerialItem::GetEditMode()
{
return CPropertyGrid::EM_INPLACE;
}
void CSerialItem::DrawItem(CDC& dc, CRect rc, bool focused)
{
string serial = m_serial;
while (serial.length()<8) serial += " ";
serial = serial.substr(0,4) + "-" + serial.substr(4,4);
rc.left += m_pGrid->GetTextMargin();
dc.DrawText(serial.c_str(), rc, DT_SINGLELINE|DT_LEFT|DT_VCENTER|DT_END_ELLIPSIS|DT_NOPREFIX);
}
string CSerialItem::GetStringForInPlaceEdit()
{
return m_serial;
}
bool CSerialItem::OnItemEdited(string strNewValue)
{
if (strNewValue.length()!=8)
{
AfxMessageBox("Invalid serial number");
return false;
}
else
{
m_serial = strNewValue;
return true;
}
}

View file

@ -0,0 +1,16 @@
#pragma once
#include "..\CustomItem.h"
class CSerialItem : public ICustomItem
{
public:
CSerialItem(void);
~CSerialItem(void);
virtual CPropertyGrid::EEditMode GetEditMode();
virtual void DrawItem(CDC& dc, CRect rc, bool focused);
virtual string GetStringForInPlaceEdit();
virtual bool OnItemEdited(string strNewValue);
protected:
string m_serial;
};

View file

@ -0,0 +1,47 @@
#include "StdAfx.h"
#include ".\treeitem.h"
CTreeItem::CTreeItem(void)
{
}
CTreeItem::~CTreeItem(void)
{
}
void CTreeItem::SetValue(string value)
{
m_value = value;
m_pGrid->Invalidate();
}
CPropertyGrid::EEditMode CTreeItem::GetEditMode()
{
return CPropertyGrid::EM_DROPDOWN;
}
void CTreeItem::DrawItem(CDC& dc, CRect rc, bool focused)
{
rc.left += m_pGrid->GetTextMargin();
dc.DrawText(m_value.c_str(), rc, DT_SINGLELINE|DT_LEFT|DT_VCENTER|DT_END_ELLIPSIS|DT_NOPREFIX);
}
void CTreeItem::ShowDropDown(CRect rc)
{
rc.top += rc.Height();
rc.bottom = rc.top + 100;
m_pGrid->ClientToScreen(&rc);
m_tree = new CCustomTreeCtrl;
m_tree->m_item = this;
m_tree->CWnd::CreateEx(0, WC_TREEVIEW, NULL, WS_POPUP|WS_BORDER|TVS_HASBUTTONS|TVS_HASLINES|TVS_LINESATROOT, rc, m_pGrid->GetParent(), 0);
m_tree->SetOwner(m_pGrid->GetParent());
HTREEITEM hf = m_tree->InsertItem("Folder 1");
m_tree->InsertItem("Item 1", hf);
m_tree->InsertItem("Item 2", hf);
m_tree->Expand(hf, TVE_EXPAND);
hf = m_tree->InsertItem("Folder 2");
m_tree->InsertItem("Item 3", hf);
m_tree->Expand(hf, TVE_EXPAND);
m_tree->ShowWindow(SW_SHOW);
m_tree->RedrawWindow();
}

View file

@ -0,0 +1,21 @@
#pragma once
#include "..\customitem.h"
#include "CustomTreeCtrl.h"
class CTreeItem :
public ICustomItem
{
public:
CTreeItem(void);
~CTreeItem(void);
virtual CPropertyGrid::EEditMode GetEditMode();
virtual void DrawItem(CDC& dc, CRect rc, bool focused);
virtual void ShowDropDown(CRect rc);
void SetValue(string value);
protected:
string m_value;
CCustomTreeCtrl* m_tree;
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View file

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
version="1.0.0.0"
processorArchitecture="X86"
name="Microsoft.Windows.PropGrid"
type="win32"
/>
<description>Your app description here</description>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="X86"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
</assembly>

View file

@ -0,0 +1,13 @@
//
// PropGrid.RC2 - resources Microsoft Visual C++ does not edit directly
//
#ifdef APSTUDIO_INVOKED
#error this file is not editable by Microsoft Visual C++
#endif //APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
// Add manually edited resources here...
/////////////////////////////////////////////////////////////////////////////

View file

@ -0,0 +1,31 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by PropGrid.rc
//
#define IDD_PROPGRID_DIALOG 102
#define IDR_MAINFRAME 128
#define IDD_RECT_EDIT 129
#define IDC_GRID 1000
#define IDC_COMBO1 1001
#define IDC_LEFT 1002
#define IDC_TOP 1003
#define IDC_COLLAPSE_ALL 1003
#define IDC_RIGHT 1004
#define IDC_EXPAND_ALL 1004
#define IDC_BOTTOM 1005
#define IDC_CUSTOM_COLORS 1005
#define IDC_CATEGORIZED 1010
#define IDC_ALPHABETICAL 1011
#define IDC_NOSORT 1012
#define IDC_DATETIMEPICKER1 1013
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 130
#define _APS_NEXT_COMMAND_VALUE 32771
#define _APS_NEXT_CONTROL_VALUE 1014
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif