HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppMinor

Win32 GDI+ memory and style

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
win32stylememorygdiand

Problem

I compiled this with wxDevC++, and it needs the GDI+ library and header includes for Windows, to compile.

On a larger program I have had memory fluctuating from plus minus 4MBs. Not a lot, but why is it doing that?

This is a short replication, which fluctuates by .1MB.

I'm wondering if there is a mistake, or is that normal? Other programs on my computer experience no fluctuation in its memory usage.

Also, I saved all the common used GDI+ tools so they did not need to be created every time. Is that good or bad?

```
// Includes
#define WIN32_LEAN_AND_MEAN
#define WINVER 0x0502
#include
#include
#include
#include
#include
#include
#include

// Global Variables
HWND hWnd;
HINSTANCE hInstance;
ULONG_PTR gdiplusToken;
int count;
Style lk;

// Functions
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
void LoadStyle();
void UnloadStyle();

int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nFunsterStil) {

// GDI+
GdiplusStartupInput gdiplusStartupInput;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

// Normal Vars
HWND hwnd;
MSG messages;
WNDCLASSEX wincl;

// window structure to register
wincl.hInstance = hThisInstance;
wincl.lpszClassName = szClassName;
wincl.lpfnWndProc = WindowProcedure;
wincl.style = CS_DBLCLKS;
wincl.cbSize = sizeof (WNDCLASSEX);
// defaults
wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
wincl.lpszMenuName = NULL;
wincl.cbClsExtra = 0;
wincl.cbWndExtra = 0;
// background color
wincl.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH);

// register window class
if (!RegisterClassEx (&wincl))
return 0;

// Create window
hwnd = CreateWindowEx(0, szClassName,

Solution

I don't know about the GDI Library but there a still some things in this code which could need a examination:

// Create window
hwnd = CreateWindowEx(0, szClassName, L"Test Transparent Static Main Window", WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_CLIPCHILDREN, 100, 100, WINDOW_WIDTH, WINDOW_HEIGHT, HWND_DESKTOP, NULL, hThisInstance, NULL);
ShowWindow(hwnd, nFunsterStil);


That is a very, very long line. It is recommended to limit the line length, so you have the option two watch two source codes next to each other on the screen.

Isn't this a lot better to read to see what goes into making this Windows?

// Create window
hwnd = CreateWindowEx(
    0, szClassName, L"Test Transparent Static Main Window", 
    WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | 
    WS_CLIPCHILDREN, 100, 100, WINDOW_WIDTH, WINDOW_HEIGHT, HWND_DESKTOP, 
    NULL, hThisInstance, NULL);


I personally stick with 80 lines per row. It forces you to write more clean code and keep the complexity in youre code down. In the end you write mire readable code For a discussion. why see here:
https://softwareengineering.stackexchange.com/questions/604/is-the-80-character-limit-still-relevant-in-times-of-widescreen-monitors

Then annother issue:

// Global Variables
HWND hWnd;
HINSTANCE hInstance;
ULONG_PTR gdiplusToken;
int count;
Style lk;


You should nearly never use global variables. They are simply a maintenance Hazard. If you feel that without them beeing global you have to pass them to too many functions then probaly it is a good reason to refactor youre code into using a class.
See https://stackoverflow.com/questions/484635/are-global-variables-bad

Annother thing is the complexity of the code. Take youre WinMain function:

int WINAPI WinMain(
    HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, 
    int nFunsterStil) {

    // GDI+
    GdiplusStartupInput gdiplusStartupInput;
    GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

    // Normal Vars
    HWND hwnd;
    MSG messages;
    WNDCLASSEX wincl;

    // window structure to register
    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;
    wincl.style = CS_DBLCLKS;
    wincl.cbSize = sizeof(WNDCLASSEX);
    // defaults
    wincl.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor(NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;
    wincl.cbClsExtra = 0;
    wincl.cbWndExtra = 0;
    // background color
    wincl.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH);

    // register window class
    if (!RegisterClassEx(&wincl))
        return 0;

    // Create window
    hwnd = CreateWindowEx(
        0, szClassName, L"Test Transparent Static Main Window", 
        WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | 
        WS_CLIPCHILDREN, 100, 100, WINDOW_WIDTH, WINDOW_HEIGHT, HWND_DESKTOP, 
        NULL, hThisInstance, NULL);

    ShowWindow(hwnd, nFunsterStil);

    // Set globals
    hWnd = hwnd;
    hInstance = hThisInstance;

    // Main window message loop
    while (GetMessage(&messages, NULL, 0, 0)) {
        TranslateMessage(&messages);
        DispatchMessage(&messages);
    }
    return messages.wParam;
}


There is a lot of stuff going on and it makes youre eyes bleed to focus on certain parts. You also realized that by commenting certain blocks what they are doing. A better approach is making the comments into functions and hiding the more low level parts.

Here the refactored method (still not perfect but to give you a hint):

```
WNDCLASSEX initWindowStructure(HINSTANCE hThisInstance)
{
WNDCLASSEX wincl;

// window structure to register
wincl.hInstance = hThisInstance;
wincl.lpszClassName = szClassName;
wincl.lpfnWndProc = WindowProcedure;
wincl.style = CS_DBLCLKS;
wincl.cbSize = sizeof(WNDCLASSEX);
// defaults
wincl.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wincl.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
wincl.hCursor = LoadCursor(NULL, IDC_ARROW);
wincl.lpszMenuName = NULL;
wincl.cbClsExtra = 0;
wincl.cbWndExtra = 0;
// background color
wincl.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH);

return wincl;
}

HWND createWindow(HINSTANCE hThisInstance)
{
return CreateWindowEx(
0, szClassName, L"Test Transparent Static Main Window",
WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX |
WS_CLIPCHILDREN, 100, 100, WINDOW_WIDTH, WINDOW_HEIGHT, HWND_DESKTOP,
NULL, hThisInstance, NULL);
}

int WINAPI WinMain(
HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument,
int nFunsterStil) {

// GDI+
GdiplusStartupInput gdiplusStartupInput;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

// Normal Vars
MSG messages;
WNDCLASSEX wincl = initWindowStructure(hThisInstance);

Code Snippets

// Create window
hwnd = CreateWindowEx(0, szClassName, L"Test Transparent Static Main Window", WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_CLIPCHILDREN, 100, 100, WINDOW_WIDTH, WINDOW_HEIGHT, HWND_DESKTOP, NULL, hThisInstance, NULL);
ShowWindow(hwnd, nFunsterStil);
// Create window
hwnd = CreateWindowEx(
    0, szClassName, L"Test Transparent Static Main Window", 
    WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | 
    WS_CLIPCHILDREN, 100, 100, WINDOW_WIDTH, WINDOW_HEIGHT, HWND_DESKTOP, 
    NULL, hThisInstance, NULL);
// Global Variables
HWND hWnd;
HINSTANCE hInstance;
ULONG_PTR gdiplusToken;
int count;
Style lk;
int WINAPI WinMain(
    HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, 
    int nFunsterStil) {

    // GDI+
    GdiplusStartupInput gdiplusStartupInput;
    GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

    // Normal Vars
    HWND hwnd;
    MSG messages;
    WNDCLASSEX wincl;

    // window structure to register
    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;
    wincl.style = CS_DBLCLKS;
    wincl.cbSize = sizeof(WNDCLASSEX);
    // defaults
    wincl.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor(NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;
    wincl.cbClsExtra = 0;
    wincl.cbWndExtra = 0;
    // background color
    wincl.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH);

    // register window class
    if (!RegisterClassEx(&wincl))
        return 0;

    // Create window
    hwnd = CreateWindowEx(
        0, szClassName, L"Test Transparent Static Main Window", 
        WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | 
        WS_CLIPCHILDREN, 100, 100, WINDOW_WIDTH, WINDOW_HEIGHT, HWND_DESKTOP, 
        NULL, hThisInstance, NULL);

    ShowWindow(hwnd, nFunsterStil);

    // Set globals
    hWnd = hwnd;
    hInstance = hThisInstance;

    // Main window message loop
    while (GetMessage(&messages, NULL, 0, 0)) {
        TranslateMessage(&messages);
        DispatchMessage(&messages);
    }
    return messages.wParam;
}
WNDCLASSEX initWindowStructure(HINSTANCE hThisInstance)
{
    WNDCLASSEX wincl;

    // window structure to register
    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;
    wincl.style = CS_DBLCLKS;
    wincl.cbSize = sizeof(WNDCLASSEX);
    // defaults
    wincl.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor(NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;
    wincl.cbClsExtra = 0;
    wincl.cbWndExtra = 0;
    // background color
    wincl.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH);

    return wincl;
}

HWND createWindow(HINSTANCE hThisInstance)
{
    return CreateWindowEx(
        0, szClassName, L"Test Transparent Static Main Window",
        WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX |
        WS_CLIPCHILDREN, 100, 100, WINDOW_WIDTH, WINDOW_HEIGHT, HWND_DESKTOP,
        NULL, hThisInstance, NULL);
}


int WINAPI WinMain(
    HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, 
    int nFunsterStil) {

    // GDI+
    GdiplusStartupInput gdiplusStartupInput;
    GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

    // Normal Vars
    MSG messages;
    WNDCLASSEX wincl = initWindowStructure(hThisInstance);

    // register window class
    if (!RegisterClassEx(&wincl))
        return 0;

    HWND hwnd  = createWindow(hThisInstance);

    ShowWindow(hwnd, nFunsterStil);

    // Set globals
    hWnd = hwnd;
    hInstance = hThisInstance;

    // Main window message loop
    while (GetMessage(&messages, NULL, 0, 0)) {
        TranslateMessage(&messages);
        DispatchMessage(&messages);
    }
    return messages.wParam;
}

Context

StackExchange Code Review Q#64593, answer score: 3

Revisions (0)

No revisions yet.