C++ Creating Window in other cpp files (not in WinMain)

1.3k Views Asked by At

I have a function that is located in a different cpp file than WinMain is, and when called will create a window. However the windows class for that new window was declared and registered inside of WinMain. Now, when I create the window in the separate function, I am forced to redeclare the 2nd and 3rd variable of the CreateWindowEx function:

_In_opt_  LPCTSTR lpClassName,
_In_opt_  LPCTSTR lpWindowName,

because the location of the function that is actually doing the creating doesn't have access to those variables that were created in WinMain. Now... my doubt is, is my program actually using the window class I registered in WinMain? For all I know, redeclaring these variables, and creating the function far away from the WinMain function could have caused the compiler to adopt some other standard window class. So, is my program actually using the window class I registered in WinMain?

Edited: giving slightly more code

//+++++++++++++++++++++++++++++++++++++cpp file with win main:

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

}

//+++++++++++++++++++++++++++++++++++++other cpp file:

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);
}

Is this last function using the window class registered in WinMain even though it is not located in WinMain and some of the variables are redeclared in the function?

1

There are 1 best solutions below

0
On BEST ANSWER

The whole point of registering a window class is so that it is unique and you can use it whenever you need to. When you register a window class using the RegisterClass[Ex] function, you have two options for identifying it:

  • The window class name (a string) that you passed into the function.
  • An ATOM (an integer value) that is returned by the function.

In 99.9% of cases, you'll forget about the ATOM and just use the string. You need the string to create the window class, so you might as well just keep up with the string and use it to create windows of that class.

Technically, what you're doing is okay, then. You have multiple variables, but they all contain exactly the same string value, so everything is working properly. But that's a maintenance nightmare, and also violates the DRY (don't repeat yourself) rule. What if you wanted to change the name of your window class? You'd have to find every file that declared it and make sure that you updated it. Then you'd have to wait forever for your entire project to recompile, because you've touched large numbers of files. No good.

Instead, you want to declare this variable at global scope, making it available in every file of your project that creates windows. Put it in a common header file that you're going to include in all of your code files, or make a separate Window.h header or something of that nature and include it where appropriate.

Do make sure that this window class name is declared as a constant. There is no reason it should ever be modified during the execution of your application.

If you're struggling with declaring and/or using global constants in C++, you might check the answers to this question or do a search of your own on Stack Overflow. This part is not unique to Windows programming; it is just basic C++.

Of course, you'll often hear that global variables are bad. That's true enough. The code that you're writing isn't really C++. It is C. The Windows API is a C API, so it naturally leads you into writing C code in C++. If you want to really write C++ code, you'll need to find (or write your own) C++ wrapper around the C-based Windows API. For example, you'd write a class that represents windows, and that class would contain a static class-level constant that holds the name of your window class. The class would be responsible for creating all new windows, so you wouldn't need to scatter that information or those implementation details across multiple code files.

As far as the window name, this is completely different. Windows doesn't use it to identify your window. In fact, it is a completely optional parameter for the CreateWindow[Ex] function. You don't even have to give the window a name. This is actually the name that appears in the window's title bar. It is used by the user to identify the window. As such, it often needs to be localized and should be stored in your project's resources file, not in the source code. Use the LoadString function to load strings from your project's resource file. You can do this dynamically whenever you create a window: just load the string you want to use as the caption for that particular window.