I have a C program and I am supposed to add an interface to it. Can I insert my code to my coded interface using Win32?
Example: Here is my code to convert binary into octal.
void biTodec(){
long long n;
int dec = 0, i = 0, rem;
printf("Enter a binary number: ");
scanf("%lld", &n);
while (n != 0) {
rem = n % 10;
n /= 10;
dec += rem * pow(2, i);
++i;
}
printf("%lld in binary = %d in decimal", n, dec);
return 0;
}
Now, I want my button in my API when clicked to perform the conversion. Here is my Win32 design
#include <stdio.h>
#include <conio.h>
#include <windows.h>
#include <stdlib.h>
LRESULT CALLBACK WindowProcedure(HWND, UINT, WPARAM,LPARAM);
void AddMenus(HWND);
void AddControls(HWND);
HMENU hMenu;
int WINAPI WinMain(HINSTANCE hinst, HINSTANCE hPrevInst, LPSTR args, int ncmdshow){
WNDCLASSW kim = {0};
kim.hbrBackground = (HBRUSH)COLOR_BACKGROUND;
kim.hCursor = LoadCursor(NULL, IDC_ARROW);
kim.hInstance = hinst;
kim.lpszClassName = L"myWindowClass";
kim.lpfnWndProc = WindowProcedure;
if(!RegisterClassW(&kim))
return -1;
CreateWindowW(L"myWindowClass",L"Number System Converter",
WS_OVERLAPPEDWINDOW | WS_VISIBLE, 100, 100, 500, 500,
NULL,NULL,NULL,NULL);
MSG msg={0};
while(GetMessage(&msg, NULL,NULL, NULL)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
LRESULT CALLBACK WindowProcedure(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp){
switch(msg){
case WM_COMMAND:
switch(wp){
case 1:
MessageBoxA(hWnd, "This project was made by bla bla for
seven (7) days. He had no any prior idea on interface so he spent
the 6 out of 7 days just for researching. Copyright 2021", "About
the
project", NULL);
break;
case 2:
MessageBeep(MB_OK);
break;
case 3:
PostQuitMessage(0);
break;
case 4:
MessageBeep(MB_OK);
break;
case 5:
MessageBeep(MB_OK);
break;
}
case WM_CREATE:
AddMenus(hWnd);
AddControls(hWnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProcW(hWnd,msg,wp,lp);
}
}
void AddMenus(HWND hWnd){
hMenu = CreateMenu();
HMENU hFileMenu = CreateMenu();
HMENU hSubMenu = CreatePopupMenu();
AppendMenu(hSubMenu,MF_STRING, 4, "File");
AppendMenu(hSubMenu,MF_STRING, 5, "Folder");
AppendMenu(hSubMenu, MF_SEPARATOR, NULL, NULL);
AppendMenu(hFileMenu,MF_POPUP,(UINT_PTR)hSubMenu, "Open");
AppendMenu(hFileMenu,MF_STRING, 2, "Save");
AppendMenu(hFileMenu, MF_SEPARATOR, NULL, NULL);
AppendMenu(hFileMenu,MF_STRING, 3, "Exit");
AppendMenu(hMenu, MF_POPUP ,(UINT_PTR)hFileMenu, "Options");
AppendMenu(hMenu, MF_POPUP ,1, "Help");
SetMenu(hWnd, hMenu);
}
void AddControls(HWND hWnd){
CreateWindowW(L"Static",L"Choose the number system to be converted",
WS_VISIBLE|WS_CHILD,100, 30, 300, 20, hWnd, NULL, NULL, NULL );
CreateWindowW(L"Edit", L"", WS_VISIBLE|WS_BORDER| WS_CHILD, 60, 80, 120, 30, hWnd, NULL, NULL,NULL);
CreateWindowW(L"Button", L"Generate", WS_VISIBLE|WS_BORDER|WS_CHILD,
200, 80, 80, 20, hWnd, NULL, NULL, NULL);
CreateWindowW(L"Edit", L"", WS_VISIBLE|WS_BORDER| WS_CHILD, 300, 80,
120, 30, hWnd, NULL, NULL,NULL);
CreateWindowW(L"Button", L"Binary",
WS_VISIBLE|WS_BORDER|WS_CHILD|BS_RADIOBUTTON|WS_TABSTOP, 60, 150,
120, 20, hWnd,NULL , NULL, NULL);
CreateWindowW(L"Button", L"Decimal",
WS_VISIBLE|WS_BORDER|WS_CHILD|BS_RADIOBUTTON|WS_TABSTOP, 60, 180,
120, 20, hWnd,NULL , NULL, NULL);
CreateWindowW(L"Button", L"Octal",
WS_VISIBLE|WS_BORDER|WS_CHILD|BS_RADIOBUTTON|WS_TABSTOP, 60, 210,
120, 20, hWnd, NULL, NULL, NULL);
CreateWindowW(L"Button", L"Hexadecimal",
WS_VISIBLE|WS_BORDER|WS_CHILD|BS_RADIOBUTTON|WS_TABSTOP,60, 240,
120, 20, hWnd, NULL, NULL, NULL);
CreateWindowW(L"Button", L"Binary",
WS_VISIBLE|WS_BORDER|WS_CHILD|BS_RADIOBUTTON|WS_TABSTOP, 300, 150,
120, 20, hWnd,NULL , NULL, NULL);
CreateWindowW(L"Button", L"Decimal",
WS_VISIBLE|WS_BORDER|WS_CHILD|BS_RADIOBUTTON|WS_TABSTOP, 300, 180,
120, 20, hWnd,NULL , NULL, NULL);
CreateWindowW(L"Button", L"Octal",
WS_VISIBLE|WS_BORDER|WS_CHILD|BS_RADIOBUTTON|WS_TABSTOP, 300, 210,
120, 20, hWnd, NULL, NULL, NULL);
CreateWindowW(L"Button", L"Hexadecimal",
WS_VISIBLE|WS_BORDER|WS_CHILD|BS_RADIOBUTTON | WS_TABSTOP, 300,
240, 120, 20, hWnd,NULL, NULL, NULL);
}
Is it possible to insert my code to the API or not? If not, can you suggest what I have to learn to create a user interface in my program?
I have fixed your code and plugged your conversion function. I have not added more conversion - you'll do it yourself with my example - nor have I added enhancements.
To fix the Windows API part, note that I have:
Saved all HWND for the controls to be able to get/set values.
Used BS_AUTORADIOBUTTON and WS_GROUP so that radio button works as usual.
Used identifiers for all controls to be able to check which operation was requested.
Fixed various warnings using appropriate casts.
#include <stdio.h>
#include <wchar.h>
#include <windows.h>
#include <windowsx.h>
#include <stdlib.h>
#include <math.h>
#define ID_CONV_SRC_BINARY 0x100
#define ID_CONV_SRC_OCTAL 0x101
#define ID_CONV_SRC_DECIMAL 0x102
#define ID_CONV_SRC_HEXADECIMAL 0x103
#define ID_CONV_DST_BINARY 0x200
#define ID_CONV_DST_OCTAL 0x201
#define ID_CONV_DST_DECIMAL 0x202
#define ID_CONV_DST_HEXADECIMAL 0x203
#define ID_GENERATE 0x300
int srcConvert = 0;
int dstConvert = 0;
LRESULT CALLBACK WindowProcedure(HWND, UINT, WPARAM, LPARAM);
void AddMenus(HWND);
void AddControls(HWND);
HMENU hMenu;
HWND hNum, hOut;
HWND hWndInEdit;
HWND hWndOutEdit;
HWND hWndSrcBinary;
HWND hWndSrcOctal;
HWND hWndSrcDecimal;
HWND hWndSrcHexadecimal;
HWND hWndDstBinary;
HWND hWndDstOctal;
HWND hWndDstDecimal;
HWND hWndDstHexadecimal;
void biTodec(
wchar_t * const inBuf,
wchar_t * const outBuf,
size_t outBufSize)
{
long long n;
int dec = 0, i = 0, rem;
if (swscanf(inBuf, L"%lld", &n) == 1) {
while (n != 0) {
rem = n % 10;
n /= 10;
dec += rem * (1 << i);//pow(2, i);
++i;
}
}
swprintf(outBuf, outBufSize, L"%d", dec);
}
int WINAPI WinMain(
_In_ HINSTANCE hinst,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPSTR lpCmdLine,
_In_ int nShowCmd)
{
WNDCLASSW kim = { 0 };
kim.hbrBackground = (HBRUSH)COLOR_BACKGROUND;
kim.hCursor = LoadCursor(NULL, IDC_ARROW);
kim.hInstance = hinst;
kim.lpszClassName = L"myWindowClass";
kim.lpfnWndProc = WindowProcedure;
if (!RegisterClassW(&kim))
return -1;
HWND hWnd = CreateWindowW(L"myWindowClass", L"Number System Converter", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
100, 100, 500, 500, NULL, NULL, NULL, NULL);
MSG msg = { 0 };
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam;
}
void Generate(HWND hWnd)
{
wchar_t inBuf[30];
wchar_t outBuf[30];
if (Button_GetCheck(hWndSrcBinary))
srcConvert = ID_CONV_SRC_BINARY;
else if (Button_GetCheck(hWndSrcDecimal))
srcConvert = ID_CONV_SRC_DECIMAL;
else if (Button_GetCheck(hWndSrcOctal))
srcConvert = ID_CONV_SRC_OCTAL;
else if (Button_GetCheck(hWndSrcHexadecimal))
srcConvert = ID_CONV_SRC_HEXADECIMAL;
else
srcConvert = 0;
if (Button_GetCheck(hWndDstBinary))
dstConvert = ID_CONV_DST_BINARY;
else if (Button_GetCheck(hWndDstDecimal))
dstConvert = ID_CONV_DST_DECIMAL;
else if (Button_GetCheck(hWndDstOctal))
dstConvert = ID_CONV_DST_OCTAL;
else if (Button_GetCheck(hWndDstHexadecimal))
dstConvert = ID_CONV_DST_HEXADECIMAL;
else
dstConvert = 0;
GetWindowText(hWndInEdit, inBuf, sizeof(inBuf) / sizeof(inBuf[0]));
if ((srcConvert & 0xFF) == (dstConvert & 0xFF))
wcscpy(outBuf, inBuf);
else if ((srcConvert == ID_CONV_SRC_BINARY) && (dstConvert == ID_CONV_DST_DECIMAL))
biTodec(inBuf, outBuf, sizeof(outBuf));
else {
MessageBox(hWnd, L"Not implemented yet", L"Warning", MB_OK);
outBuf[0] = 0;
}
SetWindowText(hWndOutEdit, outBuf);
}
LRESULT CALLBACK WindowProcedure(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{
switch (msg) {
case WM_COMMAND:
switch (wp) {
case ID_CONV_SRC_BINARY:
case ID_CONV_SRC_DECIMAL:
case ID_CONV_SRC_HEXADECIMAL:
case ID_CONV_SRC_OCTAL:
case ID_CONV_DST_BINARY:
case ID_CONV_DST_DECIMAL:
case ID_CONV_DST_HEXADECIMAL:
case ID_CONV_DST_OCTAL:
case ID_GENERATE:
Generate(hWnd);
break;
case 1:
MessageBox(hWnd, L"Copyright 2021", L"About the project", MB_OK);
break;
case 2:
MessageBeep(MB_OK);
break;
case 3:
PostQuitMessage(0);
break;
case 4:
MessageBeep(MB_OK);
break;
case 5:
MessageBeep(MB_OK);
break;
}
break;
case WM_CREATE:
AddMenus(hWnd);
AddControls(hWnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProcW(hWnd, msg, wp, lp);
}
return 0;
}
void AddMenus(HWND hWnd) {
hMenu = CreateMenu();
HMENU hFileMenu = CreateMenu();
HMENU hSubMenu = CreatePopupMenu();
AppendMenu(hSubMenu, MF_STRING, 4, L"File");
AppendMenu(hSubMenu, MF_STRING, 5, L"Folder");
AppendMenu(hSubMenu, MF_SEPARATOR, 0, NULL);
AppendMenu(hFileMenu, MF_POPUP, (UINT_PTR)hSubMenu, L"Open");
AppendMenu(hFileMenu, MF_STRING, 2, L"Save");
AppendMenu(hFileMenu, MF_SEPARATOR, 0, NULL);
AppendMenu(hFileMenu, MF_STRING, 3, L"Exit");
AppendMenu(hMenu, MF_POPUP, (UINT_PTR)hFileMenu, L"Options");
AppendMenu(hMenu, MF_POPUP, 1, L"Help");
SetMenu(hWnd, hMenu);
}
void AddControls(HWND hWnd) {
CreateWindowW(L"Static", L"Choose the number system to be converted",
WS_VISIBLE | WS_CHILD, 100,
30, 300, 20, hWnd, NULL, NULL, NULL);
hWndInEdit = CreateWindowW(L"Edit", L"", WS_VISIBLE | WS_BORDER | WS_CHILD, 60, 80, 120, 30, hWnd, NULL,
NULL, NULL);
CreateWindowW(L"Button", L"Generate", WS_VISIBLE | WS_BORDER | WS_CHILD, 200, 80, 80, 20, hWnd,
(HMENU)ID_GENERATE,
0, NULL);
hWndOutEdit = CreateWindowW(L"Edit", L"", WS_VISIBLE | WS_BORDER | WS_CHILD, 300, 80, 120, 30, hWnd, NULL,
NULL, NULL);
hWndSrcBinary = CreateWindowW(L"Button", L"Binary", WS_VISIBLE | WS_BORDER | WS_CHILD | BS_AUTORADIOBUTTON | WS_TABSTOP | WS_GROUP,
60, 150, 120, 20, hWnd, (HMENU)ID_CONV_SRC_BINARY, NULL, NULL);
hWndSrcDecimal = CreateWindowW(L"Button", L"Decimal", WS_VISIBLE | WS_BORDER | WS_CHILD | BS_AUTORADIOBUTTON,
60, 180, 120, 20, hWnd, (HMENU)ID_CONV_SRC_DECIMAL, NULL, NULL);
hWndSrcOctal = CreateWindowW(L"Button", L"Octal", WS_VISIBLE | WS_BORDER | WS_CHILD | BS_AUTORADIOBUTTON,
60, 210, 120, 20, hWnd, (HMENU)ID_CONV_SRC_OCTAL, NULL, NULL);
hWndSrcHexadecimal = CreateWindowW(L"Button", L"Hexadecimal", WS_VISIBLE | WS_BORDER | WS_CHILD | BS_AUTORADIOBUTTON,
60, 240, 120, 20, hWnd, (HMENU)ID_CONV_SRC_HEXADECIMAL, NULL, NULL);
hWndDstBinary = CreateWindowW(L"Button", L"Binary", WS_VISIBLE | WS_BORDER | WS_CHILD | BS_AUTORADIOBUTTON | WS_TABSTOP | WS_GROUP,
300, 150, 120, 20, hWnd, (HMENU)ID_CONV_DST_BINARY, NULL, NULL);
hWndDstDecimal = CreateWindowW(L"Button", L"Decimal", WS_VISIBLE | WS_BORDER | WS_CHILD | BS_AUTORADIOBUTTON, ,
300, 180, 120, 20, hWnd, (HMENU)ID_CONV_DST_DECIMAL, NULL, NULL);
hWndDstOctal = CreateWindowW(L"Button", L"Octal", WS_VISIBLE | WS_BORDER | WS_CHILD | BS_AUTORADIOBUTTON,
300, 210, 120, 20, hWnd, (HMENU)ID_CONV_DST_OCTAL, NULL, NULL);
hWndDstHexadecimal = CreateWindowW(L"Button", L"Hexadecimal", WS_VISIBLE | WS_BORDER | WS_CHILD | BS_AUTORADIOBUTTON,
300, 240, 120, 20, hWnd, (HMENU)ID_CONV_DST_HEXADECIMAL, NULL, NULL);
}
There are plenty room for enhancements. I made the minimum to answer your question. Open more questions if you need more help.
This is my first program in C using WINAPI.
When I click the button with my mouse, everything is OK, but I cannot press the button with Enter. On the other hand, Space is working.
I'm guessing that the problem is in "IsDialogMessage" but I cannot solve it.
This is my code in WinMain:
/* Run the message loop. It will run until GetMessage() returns 0 */
while (GetMessage(&msg, NULL, 0, 0))
{
if (IsDialogMessage(hwnd, &msg) && msg.wParam != VK_RETURN )
{
/* Already handled by dialog manager */
}
else {
TranslateMessage(&msg); /* Translate virtual-key messages into character messages */
DispatchMessage(&msg); /* Send message to WindowProcedure */
}
}
and this is my LRESULT CALLBACK code :
LRESULT CALLBACK wg_WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static HWND cb_handle = 0;
static HWND g_hButtonLogin = 0;
static HWND g_hButtonConfig = 0;
static HWND hEditLogin = 0;
static HWND hLabelLogin = 0;
static HWND hEditPass = 0;
static HWND hLabelPass = 0;
static int pozycja_3 = 0;
struct sesslist slist;
switch (message) /* handle the messages */
{
case WM_CREATE:
{
// LOGIN
hLabelLogin = CreateWindowEx(0, "STATIC", NULL, WS_CHILD | WS_VISIBLE | SS_LEFT, 20, 20, 40, 20, hwnd, NULL, ((LPCREATESTRUCT)lParam)->hInstance, NULL);
hEditLogin = CreateWindowEx(0, "EDIT", NULL, WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 80, 20, 150, 25,
hwnd, NULL, ((LPCREATESTRUCT)lParam)->hInstance, NULL);
// PASSWORD
hLabelPass = CreateWindowEx(0, "STATIC", NULL, WS_CHILD | WS_VISIBLE | SS_LEFT, 20, 50, 40, 20, hwnd, NULL, ((LPCREATESTRUCT)lParam)->hInstance, NULL);
hEditPass = CreateWindowEx(0, "EDIT", NULL, ES_PASSWORD | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 80, 50, 150, 25,
hwnd, NULL, ((LPCREATESTRUCT)lParam)->hInstance, NULL);
SetWindowText(hLabelLogin, "Login:");
SetWindowText(hLabelPass, "Hasło:");
// COMBOBOX
cb_handle = CreateWindowEx(0, "COMBOBOX", "", WS_CHILD | WS_VISIBLE | WS_VSCROLL | CBS_DROPDOWNLIST | WS_TABSTOP, 80, 80, 150, 25 * 4, hwnd, NULL, ((LPCREATESTRUCT)lParam)->hInstance, NULL);
get_sesslist(&slist, TRUE);
// MessageBox(hwnd, slist.sessions[1] , "yyyyy", 0);
int a = 1;
while (slist.sessions[a] != NULL)
{
SendMessage(cb_handle, CB_ADDSTRING, 0, slist.sessions[a]);
a++;
}
SendMessage(cb_handle, CB_SETCURSEL, 3, (LPARAM)"4");
/*SendMessage(cb_handle, CB_ADDSTRING, 0, (LPARAM)"MFG1");
SendMessage(cb_handle, CB_ADDSTRING, 0, (LPARAM)"MFG2");
pozycja_3 = SendMessage(cb_handle, CB_ADDSTRING, 0, (LPARAM)"3");
SendMessage(cb_handle, CB_ADDSTRING, 0, (LPARAM)"4");
SendMessage(cb_handle, CB_SETCURSEL, 0, (LPARAM)"4");*/
g_hButtonConfig = CreateWindowEx(WS_EX_CLIENTEDGE, "BUTTON", "*", WS_CHILD | WS_VISIBLE,
260, 20, 20, 20, hwnd, NULL, ((LPCREATESTRUCT)lParam)->hInstance, NULL);
Then I Create Button "Zaloguj"
g_hButtonLogin = CreateWindowEx(WS_EX_CLIENTEDGE, "BUTTON", "Zaloguj", WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_DEFPUSHBUTTON,
20, 120, 250, 30, hwnd, NULL , ((LPCREATESTRUCT)lParam)->hInstance, ((LPCREATESTRUCT)lParam)->hInstance ) ;
CenterWindow(hwnd);
SetFocus(hEditLogin);
// wg_hDlgCurrent = hEditLogin;
}
break;
case WM_COMMAND:
{
if ((HWND)lParam == g_hButtonConfig)
{
do_config();
}
if ((HWND)lParam == g_hButtonLogin || (HWND)wParam == g_hButtonLogin)
{
if (1 == 1)
{
int idx_row;
char *strText[256];
idx_row = SendMessage(cb_handle, CB_GETCURSEL, 0, 0);
SendMessage(cb_handle, CB_GETLBTEXT, idx_row, (LPARAM)strText);
wg_selected_sess = strText;
DestroyWindow(hwnd);
}
}
break;
}
case WM_DESTROY:
{
PostQuitMessage(0); /* send a WM_QUIT to the message queue */
break;
}
default: /* for messages that we don't deal with */
return DefWindowProc(hwnd, message, wParam, lParam);
}
return 0;
}
When I hit the Enter key on the "zaloguj" button, nothing happens.