我有一个函数,它位于与WinMain不同的cpp文件中,并且在调用时将创建一个窗口。但是,新窗口的Windows类已在WinMain中声明并注册。现在,当我在单独的函数中创建窗口时,我被迫重新声明CreateWindowEx函数的第二个和第三个变量:
_In_opt_ LPCTSTR lpClassName,
_In_opt_ LPCTSTR lpWindowName,
因为实际进行创建的函数的位置无法访问在WinMain中创建的那些变量。现在......我的疑问是,我的程序实际上是否正在使用我在WinMain中注册的窗口类?据我所知,重新声明这些变量,并创建远离WinMain函数的函数可能导致编译器采用其他一些标准窗口类。那么,我的程序实际上是否正在使用我在WinMain中注册的窗口类?
编辑:提供更多代码
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ p>
INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
...//previous code made the main window of the program and so forth
const char g_szClassName2[] = "windowClass2";//name of the window class
WNDCLASSEX winClass2;
HWND invisHWnd;
winClass2.cbSize = sizeof(WNDCLASSEX);
winClass2.style = 0;
winClass2.lpfnWndProc = WndProcedure2;
winClass2.cbClsExtra = 0;
winClass2.cbWndExtra = 0;
winClass2.hInstance = hInstance;
winClass2.hIcon = LoadIcon(NULL, IDI_APPLICATION);
winClass2.hCursor = LoadCursor(NULL, IDC_ARROW);
winClass2.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
winClass2.lpszMenuName = NULL;
winClass2.lpszClassName = g_szClassName2;
winClass2.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
RegisterClassEx(&winClass2);
... //other code irrelevant to issue
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++
void otherCppFile::creatingWindow()
{
const char g_szClassName2[] = "windowClass2";//name of the window class
const char WndName2[] = "winClass2";//name of the window class
HWND windowHandle = CreateWindowEx(0,
g_szClassName2,
WndName2,
WS_OVERLAPPEDWINDOW,
0,
0,
800,
500,
NULL,
NULL,
NULL,
NULL);
}
这是使用WinMain中注册的窗口类的最后一个函数,即使它不在WinMain中,并且某些变量在函数中重新声明了吗?
答案 0 :(得分:2)
注册窗口类的重点是它是唯一的,您可以随时使用它。使用RegisterClass[Ex]
函数注册窗口类时,有两种方法可以识别它:
ATOM
(整数值)。在99.9%的情况下,您将忘记ATOM
并只使用字符串。你需要字符串来创建窗口类,所以你也可以跟上字符串并用它来创建那个类的 windows 。
从技术上讲,你正在做的事情是好的。您有多个变量,但它们都包含完全相同的字符串值,因此一切正常。但那是一场维护噩梦,也违反了DRY(不要重复自己)的规则。如果您想更改窗口类的名称怎么办?您必须找到声明它的每个文件,并确保您更新它。然后,您必须永远等待整个项目重新编译,因为您已触及大量文件。不好。
相反,您希望在 global 范围内声明此变量,使其在项目的每个创建窗口的文件中都可用。将它放在您将要包含在所有代码文件中的公共头文件中,或者创建一个单独的Window.h
标题或类似的东西,并在适当的位置包含它。
确保将此窗口类名声明为常量。没有理由在执行您的应用程序时修改它。
如果你正在努力在C ++中声明和/或使用全局常量,你可以检查this question的答案,或者在Stack Overflow上搜索你自己的答案。这部分并不是Windows编程独有的;它只是基本的C ++。
当然,您经常会听到全局变量不好。这真的够了。您正在编写的代码并非真正的C ++。它是C.Windows API是一个C API,所以它自然会引导你用C ++编写C代码。如果你想真正编写C ++代码,你需要在基于C的Windows API周围找到(或编写自己的)C ++包装器。例如,您要编写一个表示窗口的类,该类将包含一个静态类级别常量,该常量包含窗口类的名称。该类将负责创建所有新窗口,因此您不会 将这些信息或那些实现细节分散到多个代码文件中。
就窗口名称而言,这是完全不同的。 Windows不会使用它来识别您的窗口。实际上,它是CreateWindow[Ex]
函数的完全可选参数。你甚至不必给窗户起名字。这实际上是窗口标题栏中显示的名称。 用户使用它来标识窗口。因此,它通常需要本地化,并且应该存储在项目的资源文件中,而不是源代码中。使用LoadString
function从项目的资源文件中加载字符串。您可以在创建窗口时动态执行此操作:只需加载要用作该特定窗口标题的字符串。