代码之家  ›  专栏  ›  技术社区  ›  CodeBlocks

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

  •  1
  • CodeBlocks  · 技术社区  · 12 年前

    我有一个函数,它位于与WinMain不同的cpp文件中,调用时将创建一个窗口。但是,该新窗口的windows类已在WinMain中声明并注册。现在,当我在单独的函数中创建窗口时,我被迫重新声明CreateWindowEx函数的第二个和第三个变量:

    _In_opt_  LPCTSTR lpClassName,
    _In_opt_  LPCTSTR lpWindowName,
    

    因为实际执行创建的函数的位置无法访问在WinMain中创建的那些变量。现在我的疑问是,我的程序实际上使用的是我在WinMain中注册的窗口类吗?据我所知,重新定义这些变量并创建远离WinMain函数的函数可能会导致编译器采用其他一些标准窗口类。那么,我的程序实际上使用的是我在WinMain中注册的窗口类吗?

    编辑:给出更多代码

    //+++++++++++++++++++++++++++++++++++++带有win main的cpp文件:

    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
    
    }
    

    //+++++++++++++++++++++++++++++++++++++其他cpp文件:

    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 回复  |  直到 12 年前
        1
  •  2
  •   Community Mohan Dere    9 年前

    注册一个 窗口类 是唯一的,您可以随时使用它。当您使用 RegisterClass[Ex] 函数,您有两个选项来识别它:

    • 传递给函数的窗口类名(字符串)。
    • 一 ATOM 函数返回的(整数值)。

    在99.9%的情况下,你会忘记 原子 只需使用字符串。你需要字符串 创造 window类,所以您最好只使用字符串并使用它来创建 窗户 该类的。

    从技术上讲,你现在做的是好的。您有多个变量,但它们都包含完全相同的字符串值,因此一切都正常工作。但这是一场维护噩梦,也违反了DRY(不要重复)规则。如果您想更改窗口类的名称怎么办?你必须找到声明它的每个文件,并确保你更新了它。然后你必须永远等待整个项目重新编译,因为你接触了大量文件。无益。

    相反,您希望在 全球的 范围,使其在创建windows的项目的每个文件中都可用。将其放在一个通用的头文件中,您可以将其包含在所有代码文件中,也可以单独制作一个 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 从项目的资源文件加载字符串。您可以在创建窗口时动态执行此操作:只需加载要用作特定窗口标题的字符串。