C ++在其他cpp文件中创建窗口(不在WinMain中)

时间:2014-08-22 13:05:52

标签: c++ winapi createwindow createwindowex

我有一个函数,它位于与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中,并且某些变量在函数中重新声明了吗?

1 个答案:

答案 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从项目的资源文件中加载字符串。您可以在创建窗口时动态执行此操作:只需加载要用作该特定窗口标题的字符串。