我在edit control
中有多个dialog box
需要接受浮点数并且locale
知道。我决定用{实现此行为{1}} subclassing
s。
为了实现edit control
认知,我决定将结构传递给SetWindowSubclass
(它将保存有关小数点分隔符,负号等的数据......)作为locale
参数。
字段的值在dwRefData
中设置但如果用户更改WM_CREATE
中的设置,则可能会更改,因此我决定更新字段的值以响应Control Panel->Regional and Language Settings
消息。
为了避免将此结构设为全局,我决定将其设为WM_SETTINGCHANGE
并在主窗口的过程中声明它。我将把它作为static
API的LPARAM
参数传递给对话框。
我不知道如何将上述结构正确传递给CreateDialogParam
和CreateDialogParam
。
问题还在于正确删除SetWindowSubclass
,以避免内存泄漏。
在通过互联网搜索后,我找不到任何有用的东西,所以现在我只有一个概念性的解决方案。
看起来应该是这样的:
subclass
在我的//declare our structure that holds locale info
struct locale_structure
{
wchar_t NegativeSign;
wchar_t separator;
};
//in my main window procedure:
static locale_structure MyStruct;
case WM_CREATE:
{
//get locale info about separator, negative sign and so on...
MyStruct->separator = //...
MyStruct->NegativeSign = //...
}
return 0L;
case WM_SETTINGCHANGE:
{
//update locale info about separator, negative sign and so on...
MyStruct->NegativeSign = //...
MyStruct->separator = //...
//...
}
// in the WM_COMMAND, to the response to a button click, pass MyStruct:
hwndSomeDlg = CreateDialogParam( ..., (LPARAM)MyStruct );
我应该dialog box
/删除subclass
,如下所示:
subclass
我应该如何将case WM_INITDIALOG:
{
/******** This is the tricky part ***********/
/// get locale structure from lParam
locale_structure MyStruct = ( locale_structure )lParam;
// pass it properly to subclassing procedures
SetWindowSubclass( GetDlgItem( hDlg, IDC_EDIT1 ), ..., MyStruct );
SetWindowSubclass( GetDlgItem( hDlg, IDC_EDIT2 ), ..., MyStruct );
/************** other stuff ***********************/
}
return TRUE;
case WM_CLOSE:
{
// perform proper cleanup to avoid memory leaks
RemoveWindowSubclass( ... );
}
传递给MyStruct
和CreateDialogParam
?
如何删除SetWindowSubclass
以避免内存泄漏?
我假设在subclassing
中也会发生一些内存分配和解除分配,你能指导我如何正确地做到这一点吗?
我提交的代码实现了我的努力解决这个问题部分中描述的概念。
程序使主窗口显示一个启动对话框的按钮。该对话框包含两个子类编辑控件。一切正常,所以我现在唯一关心的是我是否正确删除了结构。
只需创建一个空项目并复制/粘贴所需的文件:
在subclassing procedure
:
resource.h
在//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by resource.rc
//
#define IDD_DIALOG1 101
#define IDC_EDIT1 1001
#define IDC_EDIT2 1002
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 102
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1003
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
:
resource.rc
在// 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
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_DIALOG1 DIALOGEX 0, 0, 316, 180
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Dialog"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "OK",IDOK,205,159,50,14
PUSHBUTTON "Cancel",IDCANCEL,259,159,50,14
EDITTEXT IDC_EDIT1,23,20,94,17,ES_AUTOHSCROLL
EDITTEXT IDC_EDIT2,23,65,90,21,ES_AUTOHSCROLL
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
IDD_DIALOG1, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 309
TOPMARGIN, 7
BOTTOMMARGIN, 173
END
END
#endif // APSTUDIO_INVOKED
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED
:
main.cpp
感谢您的时间和帮助。
最好的问候。
答案 0 :(得分:1)
编辑2:
这是一个有效的例子(我希望):
#include "resource.h"
#include <windows.h>
#include <commctrl.h>
#include <stdlib.h>
#include <locale.h>
#include <stdio.h>
#pragma comment( lib, "comctl32.lib")
const wchar_t g_szClassName[] = L"myWindowClass";
// structure to hold locale info
typedef struct LocaleInfo
{
size_t NegativeSize, DecimalSize;
wchar_t *NegativeSign, *DecimalSeparator;
LocaleInfo()
{
NegativeSize = 0;
DecimalSize = 0;
NegativeSign = NULL;
DecimalSeparator = NULL;
}
~LocaleInfo()
{
if (NegativeSign != NULL)
{
delete[] NegativeSign;
NegativeSign = NULL;
}
if (DecimalSeparator != NULL)
{
delete[] DecimalSeparator;
DecimalSeparator = NULL;
}
}
}*pLocaleInfo;
void ReallocateInfo(wchar_t *&InsideArray, size_t &InsideSize, size_t NewSize)
{
if (NewSize == 0)
return;
wchar_t *NewArray = new wchar_t[NewSize];
delete[] InsideArray;
InsideArray = NewArray;
InsideSize = NewSize;
}
// subclassing procedure
LRESULT CALLBACK Decimalni(HWND hwnd, UINT message,
WPARAM wParam, LPARAM lParam,
UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
pLocaleInfo li = (pLocaleInfo)dwRefData;
switch (message)
{
case WM_CHAR:
{
// accept digits,decimal separatorand negative sign
// this validation is just an example
if ((isdigit(wParam)) || (wParam < L' '))
break;
else
{
for (size_t i = 0; i < 5; i++)
if ((wParam == li->DecimalSeparator[i])
|| (wParam == li->NegativeSign[i]))
{
return DefSubclassProc(hwnd, message, wParam, lParam);
break;
}
else
{
MessageBeep(0);
return FALSE;
break;
}
}
}
break;
case WM_NCDESTROY:
// should I delete structure here ??
RemoveWindowSubclass(hwnd, Decimalni, 0);
break;
}
return DefSubclassProc(hwnd, message, wParam, lParam);
}
// dialog box procedure
INT_PTR CALLBACK DlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
switch (Message)
{
case WM_INITDIALOG:
{
// subclass edit control
pLocaleInfo li = (pLocaleInfo)lParam;
SetWindowSubclass(GetDlgItem(hwnd, IDC_EDIT1),
Decimalni, 0, (DWORD_PTR)li);
SetWindowSubclass(GetDlgItem(hwnd, IDC_EDIT2),
Decimalni, 0, (DWORD_PTR)li);
}
return TRUE;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDOK:
case IDCANCEL:
EndDialog(hwnd, IDCANCEL);
break;
}
break;
default:
return FALSE;
}
return TRUE;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static pLocaleInfo li; // store decimal separator and minus sign
switch (msg)
{
case WM_CREATE:
{
/************* load current locale settings *************/
// max. len: language, country, code page
wchar_t lpszLocale[64 + 64 + 16 + 3] = L"";
wchar_t lpszVal[128];
LCID nLCID = ::GetUserDefaultLCID(); // current LCID for user
if (::GetLocaleInfo(nLCID, LOCALE_SENGLANGUAGE, lpszVal, 128))
{
wcscat_s(lpszLocale, 147, lpszVal); // language
if (::GetLocaleInfo(nLCID, LOCALE_SENGCOUNTRY, lpszVal, 128))
{
wcscat_s(lpszLocale, 147, L"_"); // append country/region
wcscat_s(lpszLocale, 147, lpszVal);
if (::GetLocaleInfo(nLCID, LOCALE_IDEFAULTANSICODEPAGE,
lpszVal, 128))
{
// missing code page or page number 0 is no error
// (e.g. with Unicode)
int nCPNum = _wtoi(lpszVal);
if (nCPNum >= 10)
{
wcscat_s(lpszLocale, 147, L"."); // append code page
wcscat_s(lpszLocale, 147, lpszVal);
}
}
}
}
// set locale and LCID
_wsetlocale(LC_ALL, lpszLocale);
::SetThreadLocale(nLCID);
/*** get information for decimal separator and negative sign ***/
li = new LocaleInfo;
ReallocateInfo(li->DecimalSeparator, li->DecimalSize, GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, NULL, NULL));
ReallocateInfo(li->NegativeSign, li->NegativeSize, GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SNEGATIVESIGN, NULL, NULL));
GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL,
li->DecimalSeparator,
li->DecimalSize);
GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SNEGATIVESIGN,
li->NegativeSign,
li->NegativeSize);
/*** create a button that launches a test dialog box *****/
HWND hButton = CreateWindowEx(0, L"Button",
L"Test subclassed edit controls in dialog box",
WS_BORDER | WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
50, 50, 350, 80, hwnd, (HMENU)8001,
GetModuleHandle(NULL), NULL);
}
break;
case WM_SETTINGCHANGE:
if (!wParam && !wcscmp((wchar_t*)lParam, L"intl"))
{
// max. len: language, country, code page
wchar_t lpszLocale[64 + 64 + 16 + 3] = L"";
wchar_t lpszVal[128];
LCID nLCID = ::GetUserDefaultLCID(); // current LCID for user
if (::GetLocaleInfo(nLCID, LOCALE_SENGLANGUAGE, lpszVal, 128))
{
wcscat_s(lpszLocale, 147, lpszVal); // language
if (::GetLocaleInfo(nLCID, LOCALE_SENGCOUNTRY, lpszVal, 128))
{
wcscat_s(lpszLocale, 147, L"_"); // append country/region
wcscat_s(lpszLocale, 147, lpszVal);
if (::GetLocaleInfo(nLCID, LOCALE_IDEFAULTANSICODEPAGE,
lpszVal, 128))
{
// missing code page or page number 0 is no error
// (e.g. with Unicode)
int nCPNum = _wtoi(lpszVal);
if (nCPNum >= 10)
{
wcscat_s(lpszLocale, 147, L"."); // append code page
wcscat_s(lpszLocale, 147, lpszVal);
}
}
}
}
// set locale and LCID
_wsetlocale(LC_ALL, lpszLocale);
::SetThreadLocale(nLCID);
/** update information for decimal separator and negative sign ***/
ReallocateInfo(li->DecimalSeparator, li->DecimalSize, GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, NULL, NULL));
ReallocateInfo(li->NegativeSign, li->NegativeSize, GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SNEGATIVESIGN, NULL, NULL));
GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL,
li->DecimalSeparator,
li->DecimalSize);
GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SNEGATIVESIGN,
li->NegativeSign,
li->NegativeSize);
return 0L;
}
else
break;
case WM_COMMAND:
{
if (LOWORD(wParam) == 8001)
{
DialogBoxParam(GetModuleHandle(NULL),
MAKEINTRESOURCE(IDD_DIALOG1), hwnd, DlgProc, (LPARAM)li);
}
}
return 0L;
case WM_CLOSE:
{
delete li;
DestroyWindow(hwnd);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
HWND hwnd;
MSG Msg;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszMenuName = NULL;
wc.lpszClassName = g_szClassName;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if (!RegisterClassEx(&wc))
{
MessageBox(NULL, L"Window Registration Failed!", L"Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
hwnd = CreateWindowEx(
0,
g_szClassName,
L"theForger's Tutorial Application",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 480, 320,
NULL, NULL, hInstance, NULL);
if (hwnd == NULL)
{
MessageBox(NULL, L"Window Creation Failed!", L"Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
while (GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
修改强>
一切都很好。您在WM_NCDESTROY
上删除它是正确的,因为它总是被调用(有时可能会跳过WM_CLOSE
)。你仍然忘记了{}
WM_CLOSE
,所以当编译器决定你需要问题时可能会遇到一些问题。
应该使用智能指针,因为如果出现问题,它应该为你释放内存,但是由你来决定。另外一个好处是它很容易适应你的代码,你基本上什么都不做。最后一点,这个“SmartPointer”是我的创作,可能仍然不完整,其他选择是unique_ptr
,shared_ptr
以及更多可以在互联网上找到的。
你去了:
#include "resource.h"
#include <Windows.h>
#include <commctrl.h>
#include <stdlib.h>
#include <locale.h>
#include <stdio.h>
#include "SmartPointer.h"
#pragma comment( lib, "comctl32.lib")
const wchar_t g_szClassName[] = L"myWindowClass";
// structure to hold locale info
struct LocaleInfo
{
wchar_t NegativeSign[5];
wchar_t DecimalSeparator[5];
};
// subclassing procedure
LRESULT CALLBACK Decimalni(HWND hwnd, UINT message,
WPARAM wParam, LPARAM lParam,
UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
SmartPointer<LocaleInfo> *li = (SmartPointer<LocaleInfo>*)dwRefData;
switch (message)
{
case WM_CHAR:
{
// accept digits,decimal separatorand negative sign
// this validation is just an example
if ((isdigit(wParam)) || (wParam < L' '))
break;
else
{
for (size_t i = 0; i < 5; i++)
if ((wParam == (*li)->DecimalSeparator[i])
|| (wParam == (*li)->NegativeSign[i]))
{
return DefSubclassProc(hwnd, message, wParam, lParam);
break;
}
else
{
MessageBeep(0);
return FALSE;
break;
}
}
}
break;
case WM_NCDESTROY:
// should I delete structure here ??
RemoveWindowSubclass(hwnd, Decimalni, 0);
break;
}
return DefSubclassProc(hwnd, message, wParam, lParam);
}
// dialog box procedure
INT_PTR CALLBACK DlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
switch (Message)
{
case WM_INITDIALOG:
{
// subclass edit control
SmartPointer<LocaleInfo> *li = (SmartPointer<LocaleInfo>*)lParam;
SetWindowSubclass(GetDlgItem(hwnd, IDC_EDIT1),
Decimalni, 0, (DWORD_PTR)li);
SetWindowSubclass(GetDlgItem(hwnd, IDC_EDIT2),
Decimalni, 0, (DWORD_PTR)li);
}
return TRUE;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDOK:
case IDCANCEL:
EndDialog(hwnd, IDCANCEL);
break;
}
break;
default:
return FALSE;
}
return TRUE;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static SmartPointer<LocaleInfo> li; // store decimal separator and minus sign
switch (msg)
{
case WM_CREATE:
{
/************* load current locale settings *************/
// max. len: language, country, code page
wchar_t lpszLocale[64 + 64 + 16 + 3] = L"";
wchar_t lpszVal[128];
LCID nLCID = ::GetUserDefaultLCID(); // current LCID for user
if (::GetLocaleInfo(nLCID, LOCALE_SENGLANGUAGE, lpszVal, 128))
{
wcscat_s(lpszLocale, 147, lpszVal); // language
if (::GetLocaleInfo(nLCID, LOCALE_SENGCOUNTRY, lpszVal, 128))
{
wcscat_s(lpszLocale, 147, L"_"); // append country/region
wcscat_s(lpszLocale, 147, lpszVal);
if (::GetLocaleInfo(nLCID, LOCALE_IDEFAULTANSICODEPAGE,
lpszVal, 128))
{
// missing code page or page number 0 is no error
// (e.g. with Unicode)
int nCPNum = _wtoi(lpszVal);
if (nCPNum >= 10)
{
wcscat_s(lpszLocale, 147, L"."); // append code page
wcscat_s(lpszLocale, 147, lpszVal);
}
}
}
}
// set locale and LCID
_wsetlocale(LC_ALL, lpszLocale);
::SetThreadLocale(nLCID);
/*** get information for decimal separator and negative sign ***/
li = SmartPointer<LocaleInfo>(LocaleInfo());
GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL,
li->DecimalSeparator,
sizeof(li->DecimalSeparator) / sizeof(li->DecimalSeparator[0]));
GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SNEGATIVESIGN,
li->NegativeSign,
sizeof(li->NegativeSign) / sizeof(li->NegativeSign[0]));
/*** create a button that launches a test dialog box *****/
HWND hButton = CreateWindowEx(0, L"Button",
L"Test subclassed edit controls in dialog box",
WS_BORDER | WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
50, 50, 350, 80, hwnd, (HMENU)8001,
GetModuleHandle(NULL), NULL);
}
break;
case WM_SETTINGCHANGE:
if (!wParam && !wcscmp((wchar_t*)lParam, L"intl"))
{
// max. len: language, country, code page
wchar_t lpszLocale[64 + 64 + 16 + 3] = L"";
wchar_t lpszVal[128];
LCID nLCID = ::GetUserDefaultLCID(); // current LCID for user
if (::GetLocaleInfo(nLCID, LOCALE_SENGLANGUAGE, lpszVal, 128))
{
wcscat_s(lpszLocale, 147, lpszVal); // language
if (::GetLocaleInfo(nLCID, LOCALE_SENGCOUNTRY, lpszVal, 128))
{
wcscat_s(lpszLocale, 147, L"_"); // append country/region
wcscat_s(lpszLocale, 147, lpszVal);
if (::GetLocaleInfo(nLCID, LOCALE_IDEFAULTANSICODEPAGE,
lpszVal, 128))
{
// missing code page or page number 0 is no error
// (e.g. with Unicode)
int nCPNum = _wtoi(lpszVal);
if (nCPNum >= 10)
{
wcscat_s(lpszLocale, 147, L"."); // append code page
wcscat_s(lpszLocale, 147, lpszVal);
}
}
}
}
// set locale and LCID
_wsetlocale(LC_ALL, lpszLocale);
::SetThreadLocale(nLCID);
/** update information for decimal separator and negative sign ***/
GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL,
li->DecimalSeparator,
sizeof(li->DecimalSeparator) / sizeof(li->DecimalSeparator[0]));
GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SNEGATIVESIGN,
li->NegativeSign,
sizeof(li->NegativeSign) / sizeof(li->NegativeSign[0]));
return 0L;
}
else
break;
case WM_COMMAND:
{
if (LOWORD(wParam) == 8001)
{
DialogBoxParam(GetModuleHandle(NULL),
MAKEINTRESOURCE(IDD_DIALOG1), hwnd, DlgProc, (LPARAM)li);
}
}
return 0L;
case WM_CLOSE:
{
DestroyWindow(hwnd);
break;
}
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
HWND hwnd;
MSG Msg;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszMenuName = NULL;
wc.lpszClassName = g_szClassName;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if (!RegisterClassEx(&wc))
{
MessageBox(NULL, L"Window Registration Failed!", L"Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
hwnd = CreateWindowEx(
0,
g_szClassName,
L"theForger's Tutorial Application",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 480, 320,
NULL, NULL, hInstance, NULL);
if (hwnd == NULL)
{
MessageBox(NULL, L"Window Creation Failed!", L"Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
while (GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
如果我是你,我会想要通过SetWindowSubclass()
或CreateDialogParam()
传递一个指针(最好是一个智能指针,它可以来自STD或自定义)。通过这种方式,它可以反映您在所有窗口中对结构进行的更改。一些简短的程序会很好,因为附近没有任何对话框模板,所以我不能给你一个如何将它传递给函数的例子。
我认为删除WM_CLOSE上的子类应该可以正常工作。
更多信息会很好。
struct locale_structure
{
wchar_t NegativeSign;
wchar_t separator;
};
static SmartPointer<locale_structure> MyStruct;
#ifndef __SMART_POINTER
#define __SMART_POINTER
#include <wtypes.h>
#include <utility>
template <class Type>
class SmartPointer
{
private:
void SmartDelete()
{
if (Pointer != nullptr && RefCount != nullptr && Size != nullptr)
{
if (RefCount[0] > 0)
RefCount[0]--;
else
{
if (Size[0] == 0)
delete Pointer;
else
delete[] Pointer;
delete RefCount;
delete Size;
}
Pointer = nullptr;
RefCount = nullptr;
Size = nullptr;
}
}
Type* Pointer;
size_t* Size;
UINT* RefCount;
public:
UINT size()
{
if (Pointer != NULL && RefCount != NULL && Size != NULL)
{
if (Size[0] == 0)
return 1;
else
return Size[0];
}
else
return 0;
}
SmartPointer() : Pointer(nullptr), Size(nullptr), RefCount(nullptr) {}
Type& operator*() { return *Pointer; }
const Type& operator*() const { return *Pointer; }
Type* operator->() { return Pointer; }
const Type* operator->() const { return Pointer; }
Type& operator[](size_t index) { return Pointer[index]; }
const Type& operator[](size_t index) const { return Pointer[index]; }
template<typename ConversionType>
operator ConversionType() { return reinterpret_cast<ConversionType>(this); }
SmartPointer(Type& Object, size_t Size = 0)
{
RefCount = new UINT();
this->Size = new size_t(Size);
if (Size == 0)
Pointer = new Type(std::move(Object));
else
{
Pointer = new Type[Size];
Pointer[0] = std::move(Object);
for (size_t i = 1; i < Size; i++)
Pointer[i] = Pointer[0];
}
}
~SmartPointer() { SmartDelete(); }
SmartPointer(SmartPointer &&OtherSP)
{
if (Pointer != OtherSP.Pointer)
{
SmartDelete();
Size = OtherSP.Size;
Pointer = OtherSP.Pointer;
RefCount = OtherSP.RefCount;
OtherSP.Size = nullptr;
OtherSP.Pointer = nullptr;
OtherSP.RefCount = nullptr;
}
}
SmartPointer& operator=(SmartPointer &&OtherSP)
{
if (Pointer != OtherSP.Pointer)
{
SmartDelete();
Size = OtherSP.Size;
Pointer = OtherSP.Pointer;
RefCount = OtherSP.RefCount;
OtherSP.Size = nullptr;
OtherSP.Pointer = nullptr;
OtherSP.RefCount = nullptr;
}
return *this;
}
SmartPointer(const SmartPointer &OtherSP)
{
if (Pointer != OtherSP.Pointer)
{
SmartDelete();
Size = OtherSP.Size;
Pointer = OtherSP.Pointer;
RefCount = OtherSP.RefCount;
RefCount[0]++;
}
else
RefCount[0]++;
}
SmartPointer& operator=(const SmartPointer &OtherSP)
{
if (Pointer != OtherSP.Pointer)
{
SmartDelete();
Size = OtherSP.Size;
Pointer = OtherSP.Pointer;
RefCount = OtherSP.RefCount;
RefCount[0]++;
}
else
RefCount[0]++;
return *this;
}
};
#endif