I'm trying to create window that contain richedit control and listbox control,
the problem is that the second control which I create, doesn't show up.
I mean:
case WM_CREATE: // In main window procedure
{
/* Center the main window */
This->CenterWindow(hwnd);
/* Initialize the clients list */
This->InitListClients(hwnd);
/* Initialize the server log */
This->InitEditLog(hwnd);
return 0;
}
If InitListClients function will be first, only the listbox will show up,
if InitEditLog will be first, only the richedit will show up.
Here are the functions:
void ApostleServer::InitEditLog(HWND &_hwnd)
{
LoadLibrary(TEXT("Riched32.dll"));
hEditLog = CreateWindowEx(WS_EX_STATICEDGE, "richedit", "bla", WS_CHILD | WS_VISIBLE | ES_MULTILINE, 10, 10, 390, 310, _hwnd, NULL, (HINSTANCE)GetWindowLong(_hwnd, GWL_HINSTANCE), NULL);
}
void ApostleServer::InitListClients(HWND &_hwnd)
{
hListClients = CreateWindowEx(WS_EX_STATICEDGE, "listbox", "bla", WS_CHILD | WS_VISIBLE | LBS_NOTIFY, 550, 20, 150, 150, _hwnd, NULL, (HINSTANCE)GetWindowLong(_hwnd, GWL_HINSTANCE), NULL);
}
I'm kinda newbie with winapi and I couldn't find solution for this problem.
Thanks.
EDIT:
As I commented, the cause of the problem is the use of class members.
Here is a whole code that I've wrote and has the same problem:
#include <Windows.h>
#include <stdlib.h>
class Server
{
public:
/* Fields */
MSG* msg;
WNDCLASSW* wc;
HWND hListClients;
HWND hEditLog;
/* Methods */
void InitEditLog(HWND &_hwnd)
{
LoadLibrary(TEXT("Riched32.dll"));
hEditLog = CreateWindowExW(WS_EX_STATICEDGE, L"richedit", L"Text", WS_CHILD | WS_VISIBLE | ES_MULTILINE, 10, 10, 390, 306, _hwnd, (HMENU)2, (HINSTANCE)GetWindowLong(_hwnd, GWL_HINSTANCE), NULL);
}
void InitListClients(HWND &_hwnd)
{
// Here I'm using hListClients class member, and that what cause the problem (I will see only the list on the window)
hListClients = CreateWindowExW(WS_EX_STATICEDGE, L"listbox", L"asd", WS_CHILD | WS_VISIBLE | LBS_NOTIFY, 410, 10, 160, 306, _hwnd, (HMENU)1, (HINSTANCE)GetWindowLong(_hwnd, GWL_HINSTANCE), NULL);
// If I was only creating the listbox (without returning handler), I will see the listbox and the richedit.
}
static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
Server* This = (Server*)GetWindowLongW(hwnd, GWL_USERDATA);
switch(msg)
{
case WM_CREATE:
{
/* Initialize the clients list */
This->InitListClients(hwnd); // Attention that I called this function first.
/* Initialize the server log */
This->InitEditLog(hwnd);
// If I would call this function first, I will see only the richedit.
return 0;
}
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
}
}
return DefWindowProcW(hwnd, msg, wParam, lParam);
}
Server(HINSTANCE &_hInstance)
{
msg = new MSG;
wc = new WNDCLASSW;
wc->style = CS_HREDRAW | CS_VREDRAW;
wc->cbClsExtra = 0;
wc->cbWndExtra = 0;
wc->lpszClassName = L"ApostleServer";
wc->hInstance = _hInstance;
wc->hbrBackground = GetSysColorBrush(COLOR_3DFACE);
wc->lpszMenuName = NULL;
wc->lpfnWndProc = WndProc;
wc->hCursor = LoadCursor(NULL, IDC_ARROW);
wc->hIcon = LoadIcon(NULL, IDI_APPLICATION);
RegisterClassW(&(*wc));
CreateWindowW(wc->lpszClassName, L"Apostle Server", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 100, 100, 600, 400, 0, 0, _hInstance, 0);
while(GetMessage(&(*msg), NULL, 0, 0))
{
TranslateMessage(&(*msg));
DispatchMessage(&(*msg));
}
}
};
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
{
Server* srvr = new Server(hInstance);
return 0;
}
Problem solved by creating the controls on WM_CREATE message (but not to set control handlers!), and set the control handlers after the creation of the main window.
WM_CREATE message:
case WM_CREATE:
{
/* Center the main window */
This->CenterWindow(hwnd);
/* Initialize the clients list */
This->InitListClients(hwnd);
/* Initialize the server log */
This->InitEditLog(hwnd);
return 0;
}
After main window creation:
RegisterClassW(&(*wc));
hMainWindow = CreateWindowW(wc->lpszClassName, L"Apostle Server", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 100, 100, 600, 400, 0, 0, _hInstance, 0);
/* Set controls handlers */
hListClients = GetDlgItem(hMainWindow, IDC_LISTCLIENTS);
hEditLog = GetDlgItem(hMainWindow, IDC_EDITLOG);
InitEditLog and InitListClients functions:
void ApostleServer::InitEditLog(HWND &_hwnd)
{
LoadLibrary(TEXT("Riched32.dll"));
CreateWindowExW(WS_EX_STATICEDGE, L"richedit", L"Text", WS_CHILD | WS_VISIBLE | ES_MULTILINE, 10, 10, 390, 306, _hwnd, (HMENU)IDC_EDITLOG, (HINSTANCE)GetWindowLong(_hwnd, GWL_HINSTANCE), NULL);
}
void ApostleServer::InitListClients(HWND &_hwnd)
{
CreateWindowExW(WS_EX_STATICEDGE, L"listbox", L"asd", WS_CHILD | WS_VISIBLE | LBS_NOTIFY, 410, 10, 160, 306, _hwnd, (HMENU)IDC_LISTCLIENTS, (HINSTANCE)GetWindowLong(_hwnd, GWL_HINSTANCE), NULL);
}
Related
My goal is to create 5 groups of radio buttons (i know it contradict with the title but you still get the point) for user choice using only Win32 API (so no window form here).
I tried using a combination of groupbox and SetWindowLongPtr but it still not working as expected (note that im using GWLP_WNDPROC as the index). If i use SetWindowLongPtr to a group box then that groupbox is gone and everything else work as expected.
I could use a "virtual" group box but it reduce the efficency of my code. Some one might recommend using WS_GROUP but it only apply if there are 2 group of radio buttons ( I think ). And i also dont like using resource so is there any solution to this problem or i just have to stuck with the "virtual" group box?
Minimal reproducible sample:
#include <Windows.h>
LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wp, LPARAM lp)
{
switch (uMsg)
{
default:
return DefWindowProc(hwnd, uMsg, wp, lp);
}
}
int WINAPI wWinMain(HINSTANCE hinst, HINSTANCE hiprevinst, PWSTR nCmdLine, int ncmdshow)
{
const wchar_t CLASS_NAME[] = L"Sample";
WNDCLASS wc = { };
wc.lpfnWndProc = WndProc;
wc.hInstance = hinst;
wc.lpszClassName = CLASS_NAME;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
RegisterClass(&wc);
HWND hwnd = CreateWindowEx(
0,
CLASS_NAME,
L"Sample window",
WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX, // Window style
CW_USEDEFAULT, CW_USEDEFAULT, 800, 600,
NULL,
NULL,
hinst,
NULL);
HWND groupbox = CreateWindowEx(0, L"Button", L"Groupbox", WS_VISIBLE | WS_CHILD | BS_GROUPBOX, 10, 10, 100, 100, NULL, NULL, hinst, NULL);
HWND radiobutton1 = CreateWindowEx(0, L"Button", L"Groupbox", WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON, 10, 10, 60, 60, groupbox, NULL, hinst, NULL);
SetWindowLongPtr(groupbox, GWLP_WNDPROC, (LONG)WndProc);
SendMessage(groupbox, NULL, NULL, TRUE);
ShowWindow(hwnd, ncmdshow);
MSG msg;
while (GetMessage(&msg, NULL, NULL, NULL))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
Due to i stripped so much of the necessary function away, you need to go to task manager and kill the process named "Autoclicker" for some reason to be able to recompile it again
Make sure you handle WM_DESTROY otherwise window won't close properly.
The radio buttons, all child dialog items, and all child windows should be created in WM_CREATE section of parent window. They need the HWND handle from parent window.
SetWindowLongPtr(.. GWLP_WNDPROC ...) is an old method used for subclassing. Your usage is incorrect. You don't need it anyway.
It's unclear what SendMessage(groupbox, NULL, NULL, TRUE); is supposed to do.
Just add the radio buttons, make sure the first radio button has an added WS_TABSTOP|WS_GROUP as shown below
LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wp, LPARAM lp)
{
switch (uMsg)
{
case WM_CREATE:
{
HINSTANCE hinst = GetModuleHandle(0);
auto add = [&](const wchar_t* name,
int id, int x, int y, int w, int h, bool first = false)
{
DWORD style = WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON;
if (first) style |= WS_GROUP | WS_TABSTOP;
return CreateWindowEx(0, L"Button", name, style,
x, y, w, h, hwnd, (HMENU)id, hinst, NULL);
};
HWND groupbox1 = CreateWindowEx(0, L"Button", L"Groupbox1",
WS_VISIBLE | WS_CHILD | BS_GROUPBOX, 2, 2, 250, 120, hwnd, NULL, hinst, NULL);
HWND radio1 = add(L"radio1", 1, 10, 30, 200, 20, true);
HWND radio2 = add(L"radio2", 2, 10, 51, 200, 20);
HWND radio3 = add(L"radio3", 3, 10, 72, 200, 20);
HWND radio4 = add(L"radio4", 4, 10, 93, 200, 20);
HWND groupbox2 = CreateWindowEx(0, L"Button", L"Groupbox2",
WS_VISIBLE | WS_CHILD | BS_GROUPBOX, 280, 2, 250, 120, hwnd, NULL, hinst, NULL);
HWND radio11 = add(L"radio1", 11, 300, 30, 200, 20, true);
HWND radio12 = add(L"radio2", 12, 300, 51, 200, 20);
HWND radio13 = add(L"radio3", 13, 300, 72, 200, 20);
HWND radio14 = add(L"radio4", 14, 300, 93, 200, 20);
return 0;
}
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
return DefWindowProc(hwnd, uMsg, wp, lp);
}
}
int WINAPI wWinMain(HINSTANCE hinst, HINSTANCE hiprevinst, PWSTR nCmdLine, int ncmdshow)
{
const wchar_t CLASS_NAME[] = L"Sample";
WNDCLASS wc = { };
wc.lpfnWndProc = WndProc;
wc.hInstance = hinst;
wc.lpszClassName = CLASS_NAME;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
RegisterClass(&wc);
HWND hwnd = CreateWindowEx(0, CLASS_NAME, L"Sample window",
WS_OVERLAPPEDWINDOW, 0, 0, 800, 600,
NULL, NULL, hinst, NULL);
ShowWindow(hwnd, ncmdshow);
MSG msg;
while (GetMessage(&msg, NULL, NULL, NULL))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
I am creating a log in screen for my app, I created the buttons but I dont know how to make my program do something when one of these buttons are pressed.Here is my code(I dont think it will be usefull)
LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) {
switch(Message) {
case WM_CREATE:
CreateWindow(TEXT("button"), TEXT("CONFIRM"), WS_VISIBLE | WS_CHILD, 355, 400, 95, 35, hwnd, NULL, NULL , NULL);
CreateWindow(TEXT("button"), TEXT("SIGN UP"), WS_VISIBLE | WS_CHILD, 50, 400, 95, 35, hwnd, NULL, NULL, NULL);
CreateWindow(TEXT("static"), TEXT("USERNAME:"), WS_VISIBLE | WS_CHILD, 50, 40, 80, 15, hwnd, NULL, NULL, NULL);
CreateWindow(TEXT("static"), TEXT("EMAIL:"), WS_VISIBLE | WS_CHILD, 85, 100, 45, 15, hwnd, NULL, NULL, NULL);
CreateWindow(TEXT("static"), TEXT("PASSWORD:"), WS_VISIBLE | WS_CHILD, 50, 160, 83, 15, hwnd, NULL, NULL, NULL);
CreateWindow(TEXT("edit"), TEXT(""), WS_VISIBLE | WS_CHILD, 135, 40, 200, 17, hwnd, NULL, NULL, NULL);
CreateWindow(TEXT("edit"), TEXT(""), WS_VISIBLE | WS_CHILD, 135, 100, 200, 17, hwnd, NULL, NULL, NULL);
CreateWindow(TEXT("edit"), TEXT(""), WS_VISIBLE | WS_CHILD, 135, 160, 200, 17, hwnd, NULL, NULL, NULL);
break;
/* Upon destruction, tell the main thread to stop */
case WM_DESTROY: {
PostQuitMessage(0);
break;
}
/* All other messages (a lot of them) are processed using default procedures */
default:
return DefWindowProc(hwnd, Message, wParam, lParam);
}
return 0;
}
/* The 'main' function of Win32 GUI programs: this is where execution starts */
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
WNDCLASSEX wc; /* A properties struct of our window */
HWND hwnd; /* A 'HANDLE', hence the H, or a pointer to our window */
MSG msg; /* A temporary location for all messages */
/* zero out the struct and set the stuff we want to modify */
memset(&wc,0,sizeof(wc));
wc.cbSize = sizeof(WNDCLASSEX);
wc.lpfnWndProc = WndProc; /* This is where we will send messages to */
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
/* White, COLOR_WINDOW is just a #define for a system color, try Ctrl+Clicking it */
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszClassName = "WindowClass";
wc.hIcon = LoadIcon(NULL,"XBM LOGO.png"); /* Load a standard icon */
wc.hIconSm = LoadIcon(NULL, "A"); /* use the name "A" to use the project icon */
if(!RegisterClassEx(&wc)) {
MessageBox(NULL, "Window Registration Failed!","Error!",MB_ICONEXCLAMATION|MB_OK);
return 0;
}
hwnd = CreateWindowEx(WS_EX_CLIENTEDGE,"WindowClass","Verification",WS_VISIBLE|WS_OVERLAPPEDWINDOW,
400, /* x */
75, /* y */
500, /* width */
600, /* height */
NULL,NULL,hInstance,NULL);
if(hwnd == NULL) {
MessageBox(NULL, "Window Creation Failed!","Error!",MB_ICONEXCLAMATION|MB_OK);
return 0;
}
/*
This is the heart of our program where all input is processed and
sent to WndProc. Note that GetMessage blocks code flow until it receives something, so
this loop will not produce unreasonably high CPU usage
*/
while(GetMessage(&msg, NULL, 0, 0) > 0) { /* If no error is received... */
TranslateMessage(&msg); /* Translate key codes to chars if present */
DispatchMessage(&msg); /* Send it to WndProc */
}
return msg.wParam;
}
NOTE: windows.h and iostream are included but there are not any other libraries
Thank you :)
The first thing you need to change is to assign an ID to your button CreateWindow calls, this is done through the HMENU parameter. The next thing you need to do is handle WM_COMMAND for those IDs and the BN_CLICKED command identifier.
For example, to assign the ID 1 to your Confirm button:
CreateWindow(TEXT("button"), TEXT("CONFIRM"), WS_VISIBLE | WS_CHILD, 355, 400, 95, 35, hwnd, (HMENU)1, NULL, NULL);
Then to handle when that is clicked:
case WM_COMMAND:
{
UINT uID = LOWORD(wParam), uCmd = HIWORD(wParam);
switch(uID)
{
case 1:
if(BN_CLICKED == uCmd)
{
/* Action here */
break;
}
else
return DefWindowProc(hWnd, uMsg, wParam, lParam);
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
}
I working on my new program about asking the user if he agree to the terms.
My program is creating a black window with a checkbox, when the user check the checkbox,
an button called "RUN" created.
My problem is that I can't change the color of the static text next to the checkbox, I must create first the checkbox and then create and change the static text.
Let me explain, my WM_CREATE is using three CreateWindow functions, one is the checkbox and after it comes the "RUN" button, and the last one is the static text, next to the checkbox.
Now, when I create first the button, the button work well and I can check it and uncheck it, but the static text is not working well.
For the static text I removed his background and change his color with WM_CTLCOLORSTATIC, but the background is not removed and the color too.
Now, when I create first the text, the text is working well and the color and the background are changed, and the button isn't working, I can't check it or uncheck it.
Please try to debug my program, it is hard to explain.
You need to try to switch between the two functions in the WM_CREATE, try to create first text and then you can see that the checkbox is not working well.
My whole program:
#include <windows.h>
#include <iostream>
#include <thread>
using namespace std;
// Text
#define IDC_STATIC 1
// Buttons
#define IDC_BUTTON 2
HWND agree, button1, text;
LRESULT CALLBACK WindowProcessMessages(HWND hwnd, UINT msg, WPARAM param, LPARAM lparam);
int WINAPI WinMain(HINSTANCE currentInstance, HINSTANCE previousInstance, PSTR cmdLine, INT cmdCount)
{
// Register the window class
const char* CLASS_NAME = "myWin32WindowClass";
WNDCLASS wc{};
wc.hInstance = currentInstance;
wc.lpszClassName = CLASS_NAME;
wc.hIcon = 0;
wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
wc.hbrBackground = CreateSolidBrush(RGB(20, 20, 20));
wc.lpfnWndProc = WindowProcessMessages;
RegisterClass(&wc);
HWND main = CreateWindow(CLASS_NAME, "WastedBit 1.6.2",
WS_VISIBLE, // Window style
CW_USEDEFAULT, CW_USEDEFAULT, // Window initial position
950, 750, // Window size
nullptr, nullptr, nullptr, nullptr);
// TopMost
SetWindowPos(main, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
// Window loop
MSG msg{};
while (GetMessage(&msg, nullptr, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
LRESULT CALLBACK WindowProcessMessages(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
switch (msg)
{
case WM_CREATE: {
button1 = CreateWindow("button", 0, WS_VISIBLE | WS_CHILD | BS_CHECKBOX, 20, 490, 15, 15, hwnd, (HMENU)1, ((LPCREATESTRUCT)lparam)->hInstance, NULL);
agree = CreateWindow("button", "RUN", WS_CHILD, 750, 525, 150, 150, hwnd, 0, 0, 0);
text = CreateWindow("static", "By checking this button, you agree to the terms above", WS_CHILD | WS_VISIBLE, 30, 490, 150, 150, hwnd, (HMENU)IDC_STATIC, 0, 0);
}
break;
case WM_COMMAND: {
BOOL checked = IsDlgButtonChecked(hwnd, 1);
if (checked) {
CheckDlgButton(hwnd, 1, BST_UNCHECKED);
ShowWindow(agree, SW_HIDE);
}
else {
CheckDlgButton(hwnd, 1, BST_CHECKED);
ShowWindow(agree, SW_SHOW);
}
}
break;
case WM_DESTROY: {
PostQuitMessage(0);
}
break;
case WM_CTLCOLORSTATIC: {
if ((HWND)lparam == GetDlgItem(hwnd, IDC_STATIC))
{
SetBkMode((HDC)wparam, TRANSPARENT);
SetTextColor((HDC)wparam, RGB(400, 0, 0));
return (BOOL)GetStockObject(NULL_BRUSH);
}
break;
}
break;
default:
return DefWindowProc(hwnd, msg, wparam, lparam);
}
}
I have tried to use it with valueless functions, but still the same.
Your problem is that you have same child-window identifiers.
Change:
button1 = CreateWindow("button", 0, WS_VISIBLE | WS_CHILD | BS_CHECKBOX, 20, 490, 15, 15, hwnd, (HMENU)1, ((LPCREATESTRUCT)lparam)->hInstance, NULL);
to something:
#define ID_BUTTON_2 101
button1 = CreateWindow("button", 0, WS_VISIBLE | WS_CHILD | BS_CHECKBOX, 20, 490, 15, 15, hwnd, (HMENU)ID_BUTTON_2, ((LPCREATESTRUCT)lparam)->hInstance, NULL);
When you receive WM_COMMAND, you should check WM_COMMAND source.
You created 3 controls, so, they can send you WM_COMMAND.
WM_COMMAND source can be known from control id ( parameter HMENU of CreateWindow ).
Here is quick fix.
case WM_COMMAND:
if( wparam == 1 ) {
BOOL checked = IsDlgButtonChecked(hwnd, 1);
if (checked) {
CheckDlgButton(hwnd, 1, BST_UNCHECKED);
ShowWindow(agree, SW_HIDE);
}
else {
CheckDlgButton(hwnd, 1, BST_CHECKED);
ShowWindow(agree, SW_SHOW);
}
}
}
break;
Okay, so I need this button that, when clicked, opens a user-specified file. After the file is opened, it needs to be read/copied into the text box below that button. Eventually other things need to happen but I'm having trouble just doing that. The following is the code I have so far for creating the GUI, then I'm completely lost on how to proceed.
#include <iostream>
#include <fstream>
#include <windows.h>
/* Declare Windows procedure */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
/* Make the class name into a global variable */
char szClassName[ ] = "WindowsApp";
int WINAPI WinMain (HINSTANCE hThisInstance,
HINSTANCE hPrevInstance,
LPSTR lpszArgument,
int nFunsterStil)
{
HWND hwnd; /* This is the handle for our window */
MSG messages; /* Here messages to the application are saved */
WNDCLASSEX wincl; /* Data structure for the windowclass */
/* The Window structure */
wincl.hInstance = hThisInstance;
wincl.lpszClassName = szClassName;
wincl.lpfnWndProc = WindowProcedure; /* This function is called by windows */
wincl.style = CS_DBLCLKS; /* Catch double-clicks */
wincl.cbSize = sizeof (WNDCLASSEX);
/* Use default icon and mouse-pointer */
wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
wincl.lpszMenuName = NULL; /* No menu */
wincl.cbClsExtra = 0; /* No extra bytes after the window class */
wincl.cbWndExtra = 0; /* structure or the window instance */
/* Use Windows's default color as the background of the window */
wincl.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
/* Register the window class, and if it fails quit the program */
if (!RegisterClassEx (&wincl))
return 0;
/* The class is registered, let's create the program*/
hwnd = CreateWindowEx (
0, /* Extended possibilites for variation */
szClassName, /* Classname */
"Software Engineering II", /* Title Text */
WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX, /* default window */
CW_USEDEFAULT, /* Windows decides the position */
CW_USEDEFAULT, /* where the window ends up on the screen */
900, /* The programs width */
500, /* and height in pixels */
HWND_DESKTOP, /* The window is a child-window to desktop */
NULL, /* No menu */
hThisInstance, /* Program Instance handler */
NULL /* No Window Creation data */
);
/* Make the window visible on the screen */
ShowWindow (hwnd, nFunsterStil);
/* Run the message loop. It will run until GetMessage() returns 0 */
while (GetMessage (&messages, NULL, 0, 0))
{
/* Translate virtual-key messages into character messages */
TranslateMessage(&messages);
/* Send message to WindowProcedure */
DispatchMessage(&messages);
}
/* The program return-value is 0 - The value that PostQuitMessage() gave */
return messages.wParam;
}
#define ID_LABEL
static HWND hwndLbl1;
static HWND hwndLbl2;
static HWND hwndLbl3;
static HWND hwndLbl4;
bool buttonPressed = false;
/* This function is called by the Windows function DispatchMessage() */
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) /* handle the messages */
{
case WM_CREATE:
hwndLbl1 = CreateWindow(TEXT("STATIC"),TEXT("Building File Selection"),
WS_VISIBLE | WS_CHILD,
10,10,150,25,
hwnd, (HMENU) 0, NULL, NULL
);
hwndLbl2 = CreateWindow(TEXT("STATIC"),TEXT("Class File Selection"),
WS_VISIBLE | WS_CHILD,
500,10,150,25,
hwnd, (HMENU) 0, NULL, NULL
);
hwndLbl3 = CreateWindow(TEXT("STATIC"),TEXT("Building No."),
WS_VISIBLE | WS_CHILD,
10, 75, 150, 25,
hwnd, (HMENU) 0, NULL, NULL
);
hwndLbl4 = CreateWindow(TEXT("STATIC"),TEXT("Room No."),
WS_VISIBLE | WS_CHILD,
500,75,150,25,
hwnd, (HMENU) 0, NULL, NULL
);
// Building Room open
CreateWindow(TEXT("button"),TEXT("Open"),
WS_VISIBLE | WS_CHILD,
10,40,80,25,
hwnd, (HMENU) 1, NULL, NULL
);
// Classroom open
CreateWindow(TEXT("button"),TEXT("Open"),
WS_VISIBLE | WS_CHILD,
500, 40, 80, 25,
hwnd, (HMENU) 2, NULL, NULL
);
CreateWindow(TEXT("button"),TEXT("Search"),
WS_VISIBLE | WS_CHILD,
800,100,80,25,
hwnd, (HMENU) 3, NULL, NULL
);
// The information should be read from here.
CreateWindow(TEXT("edit"), TEXT("Text goes here"),
WS_VISIBLE | WS_CHILD | WS_BORDER,
10, 100, 300, 20,
hwnd, (HMENU) 5, NULL, NULL
);
CreateWindow(TEXT("edit"),TEXT("Text goes here"),
WS_VISIBLE | WS_CHILD | WS_BORDER,
500,100,300,20,
hwnd, (HMENU) 5, NULL, NULL
);
CreateWindow(TEXT("edit"),TEXT("Output from Building"),
WS_CHILD | WS_VISIBLE | ES_READONLY | WS_BORDER,
10, 150, 400, 250,
hwnd, (HMENU) 6, NULL, NULL
);
CreateWindow(TEXT("edit"),TEXT("Output from Room file"),
WS_CHILD | WS_VISIBLE | ES_READONLY | WS_BORDER,
500, 150, 380, 250,
hwnd, (HMENU) 7, NULL, NULL
);
CreateWindow(TEXT("button"),TEXT("Continue"),
WS_VISIBLE | WS_CHILD,
500,410,80,25,
hwnd, (HMENU) 8, NULL, NULL
);
CreateWindow(TEXT("button"),TEXT("Show .PRN"),
WS_VISIBLE | WS_CHILD,
600,410,80,25,
hwnd, (HMENU) 9, NULL, NULL
);
CreateWindow(TEXT("button"),TEXT("Show .LOG"),
WS_VISIBLE | WS_CHILD,
700,410,80,25,
hwnd, (HMENU) 10, NULL, NULL
);
CreateWindow(TEXT("button"),TEXT("Show .CSV"),
WS_VISIBLE | WS_CHILD,
800,410,80,25,
hwnd, (HMENU) 11, NULL, NULL
);
break;
// This is where you issue commands for buttons
// To read from files and output them into those 2 text boxes that are ID'd (HMENU) 6 and (HMENU 7.
case WM_COMMAND:
if(LOWORD(wParam) == 1){
FILE * BuildingFile;
buttonPressed = true;
/* ifstream infile;
infile.open ("Bldgs-Rms-Txt-File-2012-08082012.txt");
if(infile.is_open()){
while(infile.good())
print to buildingtextbox (char) infile.get();
//BuildingFile = fopen("Bldgs-Rms-Txt-File-2012-08082012.txt","r"); // In the argument of MessageBox, this is the PARENT WINDOW, which should be the same for all
*/
}
if (LOWORD (wParam) == 2){
FILE * RoomFile;
RoomFile = fopen("cbm_005_003639_201310_08082012.DAT","r");
}
if (LOWORD (wParam) == 6){
std::cout << "chuck";
}
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;
}
1) You need to preserve the window handles (hWnd)s from the CreateWindow calls.
// Up top
#include <string>
// Class member:
HWND building1text;
// Saving the hWnd on the CreateWindow call
building1text = CreateWindow(TEXT("edit"),TEXT("Output from Building"),
WS_CHILD | WS_VISIBLE | ES_READONLY | WS_BORDER,
10, 150, 400, 250,
hwnd, (HMENU) 6, NULL, NULL
);
2) Then you can use SetWindowText(hWnd, LPCTSTR) to put the text into the text box.
string lineString, totalString;
// open file here
while(infile.good()) {
// concatenate next line from file (works if file contains
// null-terminated lines of stuff
getline(infile, lineString, '\n');
totalString += lineString;
}
SetWindowText(building1text, totalString);
I don't have a compiler set up, but hopefully that works for you. Of course, I don't know how your data file is formatted, either.
I have two edit boxes. The first edit box read the input but the second edit box for some reason gives me an empty value. I have checked the windows handle value which is not NULL. What am I supposed to do because I am very very new with GUI programming. I hope you guys can help.
#include <windows.h>
#include "GUI.h"
#include <iostream>
#include <vector>
#include <cstdio>
using namespace std;
//#include "main.h"
const char g_szClassName[] = "myWindowClass";
HWND btObj[1], lblObj, lbl2Obj, hEdit1, hEdit2;
void CreateObjects(HWND hWnd)
{
//Buttons
btObj[0] = CreateWindow(TEXT("button"), //lpClassName = type of window to create
TEXT("Process"), //lpWindowName = Name that appears on the button
WS_VISIBLE | WS_CHILD, //dwStyle = Window style flags
140, 90, // x and y coordinates of the button in pixels
105, 33, //width and height of the button in pixels
hWnd, //hWndParent = handle of the parent or main window
(HMENU)1, //Menu item ID = 1
NULL, NULL); //Set the last 2 params as null
//Labels
lblObj = CreateWindow(TEXT("edit"),
TEXT("File Input: "),
WS_VISIBLE | WS_CHILD,
16, 16,
490, 25,
hWnd,
(HMENU)2,
NULL, NULL);
//Textbox
hEdit1 = CreateWindowEx(WS_EX_CLIENTEDGE,
"EDIT", "",
WS_CHILD | WS_VISIBLE | ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL,
100, 16,
200, 25,
hWnd,
(HMENU)IDC_MAIN_INPUT,
GetModuleHandle(NULL), NULL);
//Labels
lbl2Obj = CreateWindow(TEXT("edit"),
TEXT("File Output: "),
WS_VISIBLE | WS_CHILD,
16, 55,
510, 40,
hWnd,
(HMENU)4,
NULL, NULL);
//Textbox number 2
hEdit2 = CreateWindowEx(WS_EX_CLIENTEDGE,
"EDIT", "",
WS_CHILD | WS_VISIBLE | ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL,
100, 55,
200, 25,
hWnd,
(HMENU)IDC_MAIN_OUTPUT,
GetModuleHandle(NULL), NULL);
}
// Step 4: the Window Procedure
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDC_MAIN_BUTTON:
//HWND inputFile, outputFile;
TCHAR inFile[30];
TCHAR outFile[30];
//TEXTBOX 1
HWND hEditWnd;
hEditWnd = GetDlgItem(hwnd, IDC_MAIN_INPUT);
HWND hEditWnd2;
hEditWnd2 = GetDlgItem(hwnd, IDC_MAIN_OUTPUT);
GetWindowText(hEditWnd,inFile, 30);
SetDlgItemTextA(hwnd, IDC_MAIN_INPUT, inFile);
if (hwnd == NULL)
{
MessageBox(NULL, "This hwnd is NULL Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
return 0;
}
else
{
MessageBox(NULL, "This hwnd has some value", "Error!", MB_ICONEXCLAMATION | MB_OK);
}
SetFocus (hEdit2);
GetWindowText(hEditWnd2,outFile, 30);
SetDlgItemTextA(hwnd, IDC_MAIN_OUTPUT, outFile);
MessageBox(NULL, inFile, "TESTING", MB_OK);
MessageBox(NULL, outFile, "TESTING", MB_OK);
}
break;
case WM_CREATE:
CreateObjects(hwnd);
break;
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
HWND hwnd;
MSG Msg;
//Step 1: Registering the Window Class
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszMenuName = NULL;
wc.lpszClassName = g_szClassName;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if (!RegisterClassEx(&wc))
{
MessageBox(NULL, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
return 0;
}
// Step 2: Creating the Window
hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
g_szClassName,
"CSV Converter",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
390, 200,
NULL, NULL,
hInstance, NULL);
if (hwnd == NULL)
{
MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
return 0;
}
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
// Step 3: The Message Loop
while (GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
hEditWnd = GetDlgItem(hwnd, IDC_MAIN_INPUT);
...
GetWindowText(hEditWnd,inFile, 30);
SetDlgItemTextA(hwnd, IDC_MAIN_INPUT, inFile);
You are retreiving the inFile value from the IDC_MAIN_INPUT control, and then assigning the inFile value back to the same IDC_MAIN_INPUT control.
hEditWnd2 = GetDlgItem(hwnd, IDC_MAIN_OUTPUT);
...
GetWindowText(hEditWnd2,outFile, 30);
SetDlgItemTextA(hwnd, IDC_MAIN_OUTPUT, outFile);
You are retreiving the outFile value from the IDC_MAIN_OUTPUT control, and then assigning the outFile value back to the same IDC_MAIN_OUTPUT control.
The end result: you don't see any change in the UI, because you did not actually change anything!