Search code examples
c++winapicomboboxtextbox

Win32 Combobox, print the name of selected to edit text box


I am testing out a thoery for the Combobox for win32. Many things have been tried but I am not understanding how to make it do what I want it to do. When the selection is made in the combo box I want it to print into the edit box. I believe this would be done through the handle maybe.

So if I add it to my button 1 through a cast for button 1 how do you get it to print out to the edit field??

My code is below. I left in some of the things I tried but commented it out. The problem is in add controls and I am thinking my switch and case.

I am missing that one part that populate the text to the edit box.

I am not so much new to programming so much as new to this type of programming. I am looking for a simple approach. Thanks in advance for your time.

Below is the updated code and what I got for now. I followed the guidelines for unicode. I even made friends with visual studio c++(I think).

#include <windows.h>
#include <tchar.h>
#include <iostream>

using namespace std;

#define OPTINBT1 1
#define OPTINBT2 2
#define COMBO1 3

HWND hWnd, hComboOne;

void addControl(HWND);

LPCWSTR egClassName = L"myWindowClass";

LRESULT CALLBACK WindowProcedure(HWND, UINT, WPARAM, LPARAM);


int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR args, int nCmdShow)
{

    WNDCLASSW wc = { 0 };

    wc.lpszClassName = egClassName;
    wc.lpfnWndProc = WindowProcedure;
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wc.hInstance = hInst;
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);

    if (!RegisterClassW(&wc))
    {
        const wchar_t  Error01[] = L"Register Issue To Check On : ";
        const wchar_t  Error01_Caption[] = L"Error 01";

        MessageBoxW(hWnd, Error01, Error01_Caption, MB_OK | MB_ICONERROR);

        return 0;
    }

    LPCWSTR parentWinTitle = L"My Window";

    hWnd = CreateWindowW(egClassName, parentWinTitle, WS_OVERLAPPEDWINDOW | WS_VISIBLE, 100, 100, 500, 500, NULL, NULL, NULL, NULL);

    if (hWnd == NULL)
    {

        const wchar_t Error02[] = L"Window Creation Issue To Check On : ";
        const wchar_t Error02_Caption[] = L"Window Creation Issue To Check On : ";
        MessageBoxW(hWnd, Error02, Error02_Caption, MB_OK | MB_ICONERROR);

    }
    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);


    MSG msg = { 0 };

    while (GetMessage(&msg, NULL, 0, 0))
    {

        TranslateMessage(&msg);
        DispatchMessage(&msg);

    }

    return 0;

}

LRESULT CALLBACK WindowProcedure(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{

    switch (msg)
    {
    case WM_CREATE:
        addControl(hWnd);
        break;

    case WM_COMMAND:

        if (HIWORD(wp) == CBN_SELCHANGE)
        {
            if (LOWORD(wp) == COMBO1)
            {
                HWND hcombo = (HWND)lp;
                LRESULT index = SendMessageW(hcombo, CB_GETCURSEL, (WPARAM)0, (LPARAM)0);

                wchar_t buf[256];

                SendMessageW(hcombo, (UINT)CB_GETLBTEXT, (WPARAM)index, (LPARAM)buf);
                MessageBoxW(hWnd, buf, L"Good Example", 0);
            }
            break;
        }
        switch (LOWORD(wp))
        {
        case OPTINBT1:
            MessageBoxW(hWnd, L"This is Radio button1: ", L"Radio Button 2 is good", MB_OK);
            break;
        case OPTINBT2:
            MessageBoxW(hWnd, L"This is Radio button2: ", L"Radio Button 1 is good", MB_OK);
            break;
        default:break;
        }
        break;

    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProcW(hWnd, msg, wp, lp);
    }

    return 0;
}

void addControl(HWND hWnd)
{
    HWND OptBt1, OptBt2;

    const LPCWSTR cont1 = L"STATIC";
    const LPCWSTR cont2 = L"COMBOBOX";
    const LPCWSTR cont3 = L"BUTTON";
    const LPCWSTR emptyS = L"";
    const LPCWSTR bl = L"RButton 1";
    const LPCWSTR b2 = L"RButton 2";
    //Option buttons
    OptBt1 = CreateWindowW(cont3, bl, WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON, 24, 8, 90, 25, hWnd, (HMENU)OPTINBT1, NULL, NULL);
    OptBt2 = CreateWindowW(cont3, b2, WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON, 24, 40, 90, 25, hWnd, (HMENU)OPTINBT2, NULL, NULL);
    SendMessage(OptBt1, BM_SETCHECK, BST_CHECKED, 0);

    hComboOne = CreateWindowW(cont2, emptyS, WS_VISIBLE | WS_CHILD | CBS_DROPDOWN | CBS_HASSTRINGS | WS_VSCROLL, 77, 70, 150, 150, hWnd, (HMENU)COMBO1, 0, 0);

    LPCWSTR ComboBoxItems[] = { L"Subject1", L"Subject2", L"Subject3",
        L"Subject4", L"Subject5" };

    /** Or the array way */
    SendMessageW(hComboOne, CB_ADDSTRING, 0, (LPARAM)ComboBoxItems[0]);
    SendMessageW(hComboOne, CB_ADDSTRING, 0, (LPARAM)ComboBoxItems[1]);
    SendMessageW(hComboOne, CB_ADDSTRING, 0, (LPARAM)ComboBoxItems[2]);
    SendMessageW(hComboOne, CB_ADDSTRING, 0, (LPARAM)ComboBoxItems[3]);
    SendMessageW(hComboOne, CB_ADDSTRING, 0, (LPARAM)ComboBoxItems[4]);

}

Solution

  • WM_CREATE should be inserted before addControl.

    In WM_COMMAND respond to CBN_SELCHANGE notification to detect combobox selection change.

    When you show a message box you can use the handle of your own window MessageBox(hWnd,...). If you supply NULL as the handle then the message box becomes the child of desktop window, it behaves as if it is displayed in modeless mode.

    switch(msg)
    {
    case WM_CREATE:
        addControl(hWnd);
        break;
    
    case WM_COMMAND:
        if(HIWORD(wp) == CBN_SELCHANGE)
        {
            if(LOWORD(wp) == COMBO1)
            {
                HWND hcombo = (HWND)lp;
                int index = SendMessage(hcombo, CB_GETCURSEL, (WPARAM)0, (LPARAM)0);
                char buf[256];
                SendMessage(hcombo, (UINT)CB_GETLBTEXT, (WPARAM)index, (LPARAM)buf);
                MessageBox(hWnd, buf, 0, 0);
            }
            break;
        }
    
        switch(LOWORD(wp))
        {
        case OPTINBT1:
            MessageBox(hWnd, "This is Radio button1: ", "ComboBox Working??", MB_OK);
            break;
        case OPTINBT2:
            MessageBox(hWnd, "This is Radio button2: ", "ComboBox Working??", MB_OK);
            break;
        default:break;
        }
        break;
    

    Not related to your problem, but you are mixing Unicode (example L"EDIT") with ANSI (example "EDIT").

    Window functions like CreateWindow are macros. In ANSI it is CreateWindowA, and in Unicode it is the wide function CreateWindowW

    You are compiling your program in old ANSI mode. CreateWindow is a macro to CreateWindowA which needs ANSI input. CreateWindow("EDIT",...)

    If you compile your program in Unicode, CreateWindow is a macro for the wide function CreateWindowW which uses Unicode parameter CreateWindow(L"EDIT",...)

    If you create a project in Visual Studio it will default to the new Unicode standard. Use wide char (L"Text") and Unicode functions everywhere. I would recommend compiling the program with warning level 4. Make sure the program compiles with zero warnings.