fix: #63 Creating folder in file dialog leads 64bit master crash

This commit is contained in:
yuanyuanxiang
2025-04-02 21:12:14 +08:00
parent f7abd398a4
commit 4f00cbfd6a
5 changed files with 63 additions and 277 deletions

Binary file not shown.

View File

@@ -2180,8 +2180,8 @@ void CFileManagerDlg::OnLocalNewfolder()
return;
// TODO: Add your command handler code here
CInputDialog dlg;
dlg.Init(_T("<EFBFBD>½<EFBFBD>Ŀ¼"), _T("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ¼<EFBFBD><EFBFBD><EFBFBD><EFBFBD>:"), this);
CInputDialog dlg(this);
dlg.Init(_T("<EFBFBD>½<EFBFBD>Ŀ¼"), _T("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ¼<EFBFBD><EFBFBD><EFBFBD><EFBFBD>:"));
if (dlg.DoModal() == IDOK && dlg.m_str.GetLength())
{
@@ -2197,8 +2197,8 @@ void CFileManagerDlg::OnRemoteNewfolder()
return;
// TODO: Add your command handler code here
// TODO: Add your command handler code here
CInputDialog dlg;
dlg.Init(_T("<EFBFBD>½<EFBFBD>Ŀ¼"), _T("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ¼<EFBFBD><EFBFBD><EFBFBD><EFBFBD>:"), this);
CInputDialog dlg(this);
dlg.Init(_T("<EFBFBD>½<EFBFBD>Ŀ¼"), _T("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ¼<EFBFBD><EFBFBD><EFBFBD><EFBFBD>:"));
if (dlg.DoModal() == IDOK && dlg.m_str.GetLength())
{

View File

@@ -1,227 +1,61 @@
////////////////////////////////////////////////////////////////
// MSDN Magazine -- June 2005
// If this code works, it was written by Paul DiLascia.
// If not, I don't know who wrote it.
// Compiles with Visual Studio .NET 2003 (V7.1) on Windows XP. Tab size=3.
// InputDialog.cpp: 实现文件
//
#include "stdafx.h"
#include "InputDlg.h"
#include "afxdialogex.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
//////////////////
// Note: Make sure nBufLen is big enough to hold your entire dialog template!
//
CDlgTemplateBuilder::CDlgTemplateBuilder(UINT nBufLen)
// CInputDialog 对话框
IMPLEMENT_DYNAMIC(CInputDialog, CDialogEx)
CInputDialog::CInputDialog(CWnd* pParent /*=nullptr*/)
: CDialogEx(IDD_DIALOG_INPUT, pParent)
{
m_pBuffer = new WORD[nBufLen];
m_pNext = m_pBuffer;
m_pEndBuf = m_pNext + nBufLen;
m_hIcon = NULL;
}
CDlgTemplateBuilder::~CDlgTemplateBuilder()
CInputDialog::~CInputDialog()
{
delete [] m_pBuffer;
}
//////////////////
// Create template (DLGTEMPLATE)
//
DLGTEMPLATE* CDlgTemplateBuilder::Begin(DWORD dwStyle, const CRect& rc,
LPCTSTR text, DWORD dwStyleEx)
void CInputDialog::DoDataExchange(CDataExchange* pDX)
{
ASSERT(m_pBuffer==m_pNext); // call Begin first and only once!
DLGTEMPLATE* hdr = (DLGTEMPLATE*)m_pBuffer;
hdr->style = dwStyle; // copy style..
hdr->dwExtendedStyle = dwStyleEx; // ..and extended, too
hdr->cdit = 0; // number of items: zero
// Set dialog rectangle.
CRect rcDlg = rc;
hdr->x = (short)rcDlg.left;
hdr->y = (short)rcDlg.top;
hdr->cx = (short)rcDlg.Width();
hdr->cy = (short)rcDlg.Height();
// Append trailing items: menu, class, caption. I only use caption.
m_pNext = (WORD*)(hdr+1);
*m_pNext++ = 0; // menu (none)
*m_pNext++ = 0; // dialog class (use standard)
m_pNext = AddText(m_pNext, text); // append dialog caption
ASSERT(m_pNext < m_pEndBuf);
return hdr;
CDialogEx::DoDataExchange(pDX);
}
//////////////////
// Add dialog item (control).
//
void CDlgTemplateBuilder::AddItemTemplate(WORD wType, DWORD dwStyle,
const CRect& rc, WORD nID, DWORD dwStyleEx)
{
ASSERT(m_pNext < m_pEndBuf);
// initialize DLGITEMTEMPLATE
DLGITEMTEMPLATE& it = *((DLGITEMTEMPLATE*)AlignDWORD(m_pNext));
it.style = dwStyle;
it.dwExtendedStyle = dwStyleEx;
BEGIN_MESSAGE_MAP(CInputDialog, CDialogEx)
ON_BN_CLICKED(IDOK, &CInputDialog::OnBnClickedOk)
END_MESSAGE_MAP()
CRect rcDlg = rc;
it.x = (short)rcDlg.left;
it.y = (short)rcDlg.top;
it.cx = (short)rcDlg.Width();
it.cy = (short)rcDlg.Height();
it.id = nID;
// add class (none)
m_pNext = (WORD*)(&it+1);
*m_pNext++ = 0xFFFF; // next WORD is atom
*m_pNext++ = wType; // ..atom identifier
ASSERT(m_pNext < m_pEndBuf); // check not out of range
// CInputDialog 消息处理程序
BOOL CInputDialog::Init(LPCTSTR caption, LPCTSTR prompt) {
m_sCaption = caption;
m_sPrompt = prompt;
// increment control/item count
DLGTEMPLATE* hdr = (DLGTEMPLATE*)m_pBuffer;
hdr->cdit++;
return TRUE;
}
//////////////////
// Add dialog item (control).
//
void CDlgTemplateBuilder::AddItem(WORD wType, DWORD dwStyle,
const CRect& rc, LPCTSTR text, WORD nID, DWORD dwStyleEx)
{
AddItemTemplate(wType, dwStyle, rc, nID, dwStyleEx);
m_pNext = AddText(m_pNext, text); // append title
*m_pNext++ = 0; // no creation data
ASSERT(m_pNext < m_pEndBuf);
}
//////////////////
// Add dialog item (control).
//
void CDlgTemplateBuilder::AddItem(WORD wType, DWORD dwStyle,
const CRect& rc, WORD wResID, WORD nID, DWORD dwStyleEx)
{
AddItemTemplate(wType, dwStyle, rc, nID, dwStyleEx);
*m_pNext++ = 0xFFFF; // next is resource id
*m_pNext++ = wResID; // ..here it is
*m_pNext++ = 0; // no extra stuff
ASSERT(m_pNext < m_pEndBuf);
}
//////////////////
// Append text to buffer. Convert to Unicode if necessary.
// Return pointer to next character after terminating NULL.
//
WORD* CDlgTemplateBuilder::AddText(WORD* buf, LPCTSTR text)
{
if (text) {
USES_CONVERSION;
wcscpy((WCHAR*)buf, T2W((LPTSTR)text));
buf += wcslen((WCHAR*)buf)+1;
} else {
*buf++ = 0;
}
return buf;
}
//////////////////
// Create string dialog. If no icon specified, use IDI_QUESTION. Note that
// the order in which the controls are added is the TAB order.
//
BOOL CInputDialog::Init(LPCTSTR caption, LPCTSTR prompt, CWnd* pParent, INT_PTR nIDIcon)
{
const int CXDIALOG = 200; // dialog width
const int DLGMARGIN = 7; // margins all around
const int CYSTATIC = 8; // height of static text
const int CYEDIT = 12; // height of edit control
const int CYSPACE = 5; // vertical space between controls
const int CXBUTTON = 40; // button width...
const int CYBUTTON = 15; // ..and height
CDlgTemplateBuilder& dtb = m_dtb;
CRect rc(
CPoint(0,0),
CSize(CXDIALOG, CYSTATIC + CYEDIT + CYBUTTON + 2*DLGMARGIN + 2*CYSPACE));
// create dialog header
DLGTEMPLATE* pTempl = dtb.Begin(WS_POPUPWINDOW|DS_MODALFRAME|WS_DLGFRAME,rc,caption);
// shrink main rect by margins
rc.DeflateRect(CSize(DLGMARGIN,DLGMARGIN));
// create icon if needed
if (nIDIcon) {
if (nIDIcon >= (INT_PTR)IDI_APPLICATION) {
// if using a system icon, I load it here and set it in OnInitDialog
// because can't specify system icon in template, only icons from
// application resource file.
m_hIcon = ::LoadIcon(NULL, MAKEINTRESOURCE(nIDIcon));
nIDIcon = 0;
} else {
m_hIcon = NULL;
}
// The size is calculated in pixels, but it seems to work OK--???
CSize sz(GetSystemMetrics(SM_CXICON),GetSystemMetrics(SM_CYICON));
CRect rcIcon(rc.TopLeft(), sz);
dtb.AddItem(CDlgTemplateBuilder::STATIC, // add icon
WS_VISIBLE|WS_CHILD|SS_LEFT|SS_ICON, rc, nIDIcon, IDICON);
rc.left += sz.cx; // shrink main rect by width of icon
}
// add prompt
rc.bottom = rc.top + CYSTATIC; // height = height of static
dtb.AddItem(CDlgTemplateBuilder::STATIC, // add it
WS_VISIBLE|WS_CHILD|SS_LEFT, rc, prompt);
// add edit control
rc += CPoint(0, rc.Height() + CYSPACE); // move below static
rc.bottom = rc.top + CYEDIT; // height = height of edit control
dtb.AddItem(CDlgTemplateBuilder::EDIT, // add it ES_AUTOHSCROLL must be add
WS_VISIBLE|WS_CHILD|WS_BORDER|WS_TABSTOP|ES_AUTOHSCROLL, rc, m_str, IDEDIT);
// add OK button
rc += CPoint(0, rc.Height() + CYSPACE); // move below edit control
rc.bottom = rc.top + CYBUTTON; // height = button height
rc.left = rc.right - CXBUTTON; // width = button width
rc -= CPoint(CXBUTTON + DLGMARGIN,0); // move left one button width
dtb.AddItem(CDlgTemplateBuilder::BUTTON, // add it
WS_VISIBLE|WS_CHILD|WS_TABSTOP|BS_DEFPUSHBUTTON, rc, _T("&OK"), IDOK);
// add Cancel button
rc += CPoint(CXBUTTON + DLGMARGIN,0); // move right again
dtb.AddItem(CDlgTemplateBuilder::BUTTON, // add Cancel button
WS_VISIBLE|WS_CHILD|WS_TABSTOP, rc, _T("&Cancel"), IDCANCEL);
return InitModalIndirect(pTempl, pParent);
}
//////////////////
// Initialize dialog: if I loaded a system icon, set it in static control.
//
BOOL CInputDialog::OnInitDialog()
{
if (m_hIcon) {
CStatic* pStatic = (CStatic*)GetDlgItem(IDICON);
ASSERT(pStatic);
pStatic->SetIcon(m_hIcon);
}
return CDialog::OnInitDialog();
CDialogEx::OnInitDialog();
SetIcon(m_hIcon, FALSE);
SetWindowText(m_sCaption);
GetDlgItem(IDC_STATIC)->SetWindowText(m_sPrompt);
return TRUE; // return TRUE unless you set the focus to a control
// 异常: OCX 属性页应返回 FALSE
}
/////////////////
// User pressed OK: check for empty string if required flag is set.
//
void CInputDialog::OnOK()
void CInputDialog::OnBnClickedOk()
{
UpdateData(TRUE);
if (m_bRequired && m_str.IsEmpty()) {
MessageBeep(0);
return; // don't quit dialog!
}
CDialog::OnOK();
GetDlgItem(IDC_EDIT_FOLDERNAME)->GetWindowText(m_str);
CDialogEx::OnOK();
}

View File

@@ -1,83 +1,35 @@
////////////////////////////////////////////////////////////////
// PixieLib(TM) Copyright 1997-2005 Paul DiLascia
// If this code works, it was written by Paul DiLascia.
// If not, I don't know who wrote it.
// Compiles with Visual Studio.NET 7.1 or greater. Set tabsize=3.
//
#pragma once
//////////////////
// Helper class to build a dialog template in memory. Only supports what's
// needed for CStringDialog.
//
class CDlgTemplateBuilder {
protected:
WORD* m_pBuffer; // internal buffer holds dialog template
WORD* m_pNext; // next WORD to copy stuff
WORD* m_pEndBuf; // end of buffer
#include "resource.h"
// align ptr to nearest DWORD
WORD* AlignDWORD(WORD* ptr) {
ptr++; // round up to nearest DWORD
LPARAM lp = (LPARAM)ptr; // convert to long
lp &= 0xFFFFFFFC; // make sure on DWORD boundary
return (WORD*)lp;
}
// CInputDialog 对话框
void AddItemTemplate(WORD wType, DWORD dwStyle, const CRect& rc,
WORD nID, DWORD dwStyleEx);
class CInputDialog : public CDialogEx
{
DECLARE_DYNAMIC(CInputDialog)
public:
// Windows predefined atom names
enum { BUTTON=0x0080, EDIT, STATIC, LISTBOX, SCROLLBAR, COMBOBOX };
CInputDialog(CWnd* pParent = nullptr); // 标准构造函数
virtual ~CInputDialog();
CDlgTemplateBuilder(UINT nBufLen=1024);
~CDlgTemplateBuilder();
BOOL Init(LPCTSTR caption, LPCTSTR prompt);
DLGTEMPLATE* GetTemplate() { return (DLGTEMPLATE*)m_pBuffer; }
// 对话框数据
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_DIALOG_INPUT };
#endif
// functions to build the template
DLGTEMPLATE* Begin(DWORD dwStyle, const CRect& rc, LPCTSTR caption, DWORD dwStyleEx=0);
WORD* AddText(WORD* buf, LPCTSTR text);
void AddItem(WORD wType, DWORD dwStyle, const CRect& rc,
LPCTSTR text, WORD nID=-1, DWORD dwStyleEx=0);
void AddItem(WORD wType, DWORD dwStyle, const CRect& rc,
WORD nResID, WORD nID=-1, DWORD dwStyleEx=0);
};
//////////////////
// Class to implement a simple string input dialog. Kind of like MessageBox
// but it accepts a single string input from user. You provide the prompt. To
// use:
//
// CStringDialog dlg; // string dialog
// dlg.m_bRequired = m_bRequired; // if string is required
// dlg.Init(_T("Title"), _T("Enter a string:"), this, IDI_QUESTION);
// dlg.DoModal(); // run dialog
// CString result = dlg.m_str; // whatever the user typed
//
class CInputDialog : public CDialog {
public:
CString m_str; // the string returned [in,out]
BOOL m_bRequired; // string required?
HICON m_hIcon; // icon if not supplied
CInputDialog() { }
~CInputDialog() { }
// Call this to create the template with given caption and prompt.
BOOL Init(LPCTSTR caption, LPCTSTR prompt, CWnd* pParent=NULL,
INT_PTR nIDIcon=(INT_PTR)IDI_QUESTION);
protected:
CDlgTemplateBuilder m_dtb; // place to build/hold the dialog template
enum { IDICON=1, IDEDIT }; // control IDs
// MFC virtual overrides
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
DECLARE_MESSAGE_MAP()
HICON m_hIcon;
CString m_sCaption;
CString m_sPrompt;
public:
CString m_str;
virtual BOOL OnInitDialog();
virtual void OnOK();
virtual void DoDataExchange(CDataExchange* pDX)
{
DDX_Text(pDX, IDEDIT, m_str);
}
afx_msg void OnBnClickedOk();
};

Binary file not shown.