Click here to Skip to main content
15,889,992 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Is there another way to work with Menu controls ? In my code I have a vast menu with a lots of elements(sub menu items). But the problem is, how to write less lines, when the user access an item from the sub menu, lots of static controls like buttons and static windows etc. appears in the main window as they should, but when you pass to another element of the menu I need to write a bunch of code in the VM_COMMAND for any single ID, and send tons of message to close them, way that they don't remain in the client area.

C++
#include <windows.h>
#include "resources.h"

HWND hAmazonB, hAssassinB, hNecromancerB, hBarbarianB, hPaladinB, hSorceressB, hDruidB, hAmazonS, hAssassinS, hNecromancerS, hBarbarianS, hPaladinS, hSorceressS, hDruidS;

void CharBasics(HWND hWnd)
{
    hAmazonB        = CreateWindowW(L"button", NULL, WS_CHILD | WS_VISIBLE | BS_BITMAP,
                             0, 0, 80, 32, hWnd, (HMENU)IDBAMAB, NULL, NULL);
    SendMessage(hAmazonB, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBut1);
    hAssassinB      = CreateWindowW(L"button", NULL, WS_CHILD | WS_VISIBLE | BS_BITMAP,
                             81, 0, 80, 32, hWnd, (HMENU)IDBASAB, NULL, NULL);
    SendMessage(hAssassinB, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBut2);
    hNecromancerB   = CreateWindowW(L"button", NULL, WS_CHILD | WS_VISIBLE | BS_BITMAP,
                             162, 0, 80, 32, hWnd, (HMENU)IDBNECB, NULL, NULL);
    SendMessage(hNecromancerB, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBut3);
    hBarbarianB     = CreateWindowW(L"button", NULL, WS_CHILD | WS_VISIBLE | BS_BITMAP,
                             243, 0, 80, 32, hWnd, (HMENU)IDBBARB, NULL, NULL);
    SendMessage(hBarbarianB, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBut4);
    hPaladinB       = CreateWindowW(L"button", NULL, WS_CHILD | WS_VISIBLE | BS_BITMAP,
                             324, 0, 80, 32, hWnd, (HMENU)IDBPALB, NULL, NULL);
    SendMessage(hPaladinB, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBut5);
    hSorceressB     = CreateWindowW(L"button", NULL, WS_CHILD | WS_VISIBLE | BS_BITMAP,
                             405, 0, 80, 32, hWnd, (HMENU)IDBSORB, NULL, NULL);
    SendMessage(hSorceressB, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBut6);
    hDruidB         = CreateWindowW(L"button", NULL, WS_CHILD | WS_VISIBLE | BS_BITMAP,
                             486, 0, 80, 32, hWnd, (HMENU)IDBDRUB, NULL, NULL);
    SendMessage(hDruidB, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBut7);
    hCBdesc         = CreateWindowW(L"static", L"   Character Basics Description",
                                    WS_CHILD | WS_VISIBLE | SS_CENTER, 567, 0, 167, 32, hWnd, NULL, NULL, NULL);
    hCloseAll       = CreateWindowW(L"button", NULL, WS_CHILD | WS_VISIBLE | BS_BITMAP,
                                    735, 0, 60, 32, hWnd, (HMENU)IDBCLOSE, NULL, NULL);
    SendMessage(hCloseAll, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBut8);

}
void CharSkills(HWND hWnd)
{
    hAmazonS        = CreateWindowW(L"button", NULL, WS_CHILD | WS_VISIBLE | BS_BITMAP,
                             0, 0, 80, 32, hWnd, (HMENU)IDBAMAS, NULL, NULL);
    SendMessage(hAmazonS, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBut1);
    hAssassinS      = CreateWindowW(L"button", NULL, WS_CHILD | WS_VISIBLE | BS_BITMAP,
                             81, 0, 80, 32, hWnd, (HMENU)IDBASAS, NULL, NULL);
    SendMessage(hAssassinS, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBut2);
    hNecromancerS   = CreateWindowW(L"button", NULL, WS_CHILD | WS_VISIBLE | BS_BITMAP,
                             162, 0, 80, 32, hWnd, (HMENU)IDBNECS, NULL, NULL);
    SendMessage(hNecromancerS, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBut3);
    hBarbarianS     = CreateWindowW(L"button", NULL, WS_CHILD | WS_VISIBLE | BS_BITMAP,
                             243, 0, 80, 32, hWnd, (HMENU)IDBBARS, NULL, NULL);
    SendMessage(hBarbarianS, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBut4);
    hPaladinS       = CreateWindowW(L"button", NULL, WS_CHILD | WS_VISIBLE | BS_BITMAP,
                             324, 0, 80, 32, hWnd, (HMENU)IDBPALS, NULL, NULL);
    SendMessage(hPaladinS, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBut5);
    hSorceressS     = CreateWindowW(L"button", NULL, WS_CHILD | WS_VISIBLE | BS_BITMAP,
                             405, 0, 80, 32, hWnd, (HMENU)IDBSORS, NULL, NULL);
    SendMessage(hSorceressS, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBut6);
    hDruidS         = CreateWindowW(L"button", NULL, WS_CHILD | WS_VISIBLE | BS_BITMAP,
                             486, 0, 80, 32, hWnd, (HMENU)IDBDRUS, NULL, NULL);
    SendMessage(hDruidS, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBut7);
    hCSdesc         = CreateWindowW(L"static", L"   Character Skills Description",
                                    WS_CHILD | WS_VISIBLE | SS_CENTER, 567, 0, 167, 32, hWnd, NULL, NULL, NULL);
    hCloseAll       = CreateWindowW(L"button", NULL, WS_CHILD | WS_VISIBLE | BS_BITMAP,
                                    735, 0, 60, 32, hWnd, (HMENU)IDBCLOSE, NULL, NULL);
    SendMessage(hCloseAll, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBut8);
}
void ReadOnlyControl(HWND hWnd)
{
    hReadOnly = CreateWindowW(L"edit", NULL, WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY,
                              0, 34, 795, 445, hWnd, NULL, NULL, NULL);
}
//Main Loop
LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{
    switch(msg)
    {
    case WM_COMMAND:
        switch(wp)
        {
        case ID_BASICS:
            {
                SendMessage((HWND)hAmazonB, WM_CLOSE, 0, 0);
                SendMessage((HWND)hAssassinB, WM_CLOSE, 0, 0);
                SendMessage((HWND)hNecromancerB, WM_CLOSE, 0, 0);
                SendMessage((HWND)hBarbarianB, WM_CLOSE, 0, 0);
                SendMessage((HWND)hPaladinB, WM_CLOSE, 0, 0);
                SendMessage((HWND)hSorceressB, WM_CLOSE, 0, 0);
                SendMessage((HWND)hDruidB, WM_CLOSE, 0, 0);
                SendMessage((HWND)hAmazonS, WM_CLOSE, 0, 0);
                SendMessage((HWND)hAssassinS, WM_CLOSE, 0, 0);
                SendMessage((HWND)hNecromancerS, WM_CLOSE, 0, 0);
                SendMessage((HWND)hBarbarianS, WM_CLOSE, 0, 0);
                SendMessage((HWND)hPaladinS, WM_CLOSE, 0, 0);
                SendMessage((HWND)hSorceressS, WM_CLOSE, 0, 0);
                SendMessage((HWND)hDruidS, WM_CLOSE, 0, 0);
                SendMessage((HWND)hReadOnly, WM_CLOSE, 0, 0);
                sendmessage((HWND))
                CharBasics(hWnd);
                return DefWindowProcW(hWnd, msg, wp, lp);
            }
        case ID_SKILLS:
            {
                SendMessage((HWND)hAmazonB, WM_CLOSE, 0, 0);
                SendMessage((HWND)hAssassinB, WM_CLOSE, 0, 0);
                SendMessage((HWND)hNecromancerB, WM_CLOSE, 0, 0);
                SendMessage((HWND)hBarbarianB, WM_CLOSE, 0, 0);
                SendMessage((HWND)hPaladinB, WM_CLOSE, 0, 0);
                SendMessage((HWND)hSorceressB, WM_CLOSE, 0, 0);
                SendMessage((HWND)hDruidB, WM_CLOSE, 0, 0);
                SendMessage((HWND)hAmazonS, WM_CLOSE, 0, 0);
                SendMessage((HWND)hAssassinS, WM_CLOSE, 0, 0);
                SendMessage((HWND)hNecromancerS, WM_CLOSE, 0, 0);
                SendMessage((HWND)hBarbarianS, WM_CLOSE, 0, 0);
                SendMessage((HWND)hPaladinS, WM_CLOSE, 0, 0);
                SendMessage((HWND)hSorceressS, WM_CLOSE, 0, 0);
                SendMessage((HWND)hDruidS, WM_CLOSE, 0, 0);
                SendMessage((HWND)hReadOnly, WM_CLOSE, 0, 0);
                CharSkills(hWnd);
                return DefWindowProcW(hWnd, msg, wp, lp);
            }
        }
   default:
        return DefWindowProcW(hWnd, msg, wp, lp);
    }
    return 0;
}


What I have tried:

I only tryed with SendMessage..
Posted
Updated 22-Jun-20 8:15am
v2

1 solution

When I see a problem like this the first thing I do is look for repeated code sequences. You have quite a few of those here. Here is one :
C++
hAmazonB = CreateWindowW( L"button", NULL, WS_CHILD | WS_VISIBLE | BS_BITMAP,
                         0, 0, 80, 32, hWnd, (HMENU) IDBAMAB, NULL, NULL );
SendMessage( hAmazonB, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM) hBut1 );
It also seems that CharBasics and CharSkills are virtually the same. Furthermore, the WM_COMMAND handling is almost identical for the two cases.

When I see repeated code sequences I then think about how I could make a function to eliminate that repeated code. Here is one function that could simplify a lot of code for you :
C++
HWND CreateBitmapButton( int x1, int y1, HWND hParent, UINT id, HWND hButton )
{
    HWND hw = CreateWindowW( L"button", NULL, WS_CHILD | WS_VISIBLE | BS_BITMAP,
                             x1, y1, 80, 32, hParent, (HMENU) id, NULL, NULL );
    SendMessage( hw, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM) hButton );
    return hw;
}
Then I would save all of the window handles for those button into a vector or array so that in the WM_COMMAND handler you can call a function that loops through that vector or array and sends WM_CLOSE to each of them.

With this function your code could become :
C++
Buttons[ Amazon ] = CreateBitmapButton( 0, 0, hWnd, IDBAMAB, hBut1 );
Buttons[ Assassin ] = CreateBitmapButton( 81, 0, hWnd, IDBASAB, hBut2 );
This assumes you made an array of buttons and you defined an enumeration for your characters.

By keeping your controls in arrays (or vectors) you can greatly simplify the code you use because it can be mostly a series of loops and functions. The next evolution can be a class to represent a character and have it encapsulate the code you use on each element of the array(s).
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900