The usual, whats wrong here?
Sup friends,
Now that I'm getting used to Win32, I have less trouble at it then before, but for some reason his code does not work, why? -
#include <windows>
const char *ClsName = "BasicApp";
const char *WndName = "A Simple Window";
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg,
WPARAM wParam, LPARAM lParam);
INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MSG Msg;
HWND hWnd;
WNDCLASSEX WndClsEx;
// Create the application window
WndClsEx.cbSize = sizeof(WNDCLASSEX);
WndClsEx.style = CS_HREDRAW | CS_VREDRAW;
WndClsEx.lpfnWndProc = WndProc;
WndClsEx.cbClsExtra = 0;
WndClsEx.cbWndExtra = 0;
WndClsEx.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClsEx.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClsEx.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
WndClsEx.lpszMenuName = NULL;
WndClsEx.lpszClassName = ClsName;
WndClsEx.hInstance = hInstance;
WndClsEx.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
// Register the application
RegisterClassEx(&WndClsEx);
// Create the window object
hWnd = CreateWindow(ClsName,
WndName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);
// Find out if the window was created
if( !hWnd ) // If the window was not created,
return 0; // stop the application
// Display the window to the user
ShowWindow(hWnd, SW_SHOWNORMAL);
UpdateWindow(hWnd);
// Decode and treat the messages
// as long as the application is running
while( GetMessage(&Msg, NULL, 0, 0) )
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
int xPos = GET_X_LPARAM(lParam);
int yPos = GET_Y_LPARAM(lParam);
if (Msg==WM_LBUTTONDOWN) {
MessageBox(NULL, "X = " + xPos + "\nY = " + yPos, "Mouse's Area", MB_OK);}
else if (Msg==WM_DESTROY) PostQuitMessage(WM_QUIT);
else return DefWindowProc(hWnd, Msg, wParam, lParam);
return 0;
}
It should simply just display X+Y positions of the mouse but it ends up giving errors instead.
Could someone please help?
Thanks.
# 1 Re: The usual, whats wrong here?
Sup friends,
MessageBox(NULL, "X = " + xPos + "\nY = " + yPos, "Mouse's Area", MB_OK);}
}
Code tags would be nice.
You can't just throw string literals and ints and plus signs together like that in C++.
GCDEF at 2007-11-9 1:24:32 >

# 2 Re: The usual, whats wrong here?
The MessageBox function takes char*.
You tried to pass a collection of static char arrays and integers.
There is no implicit conversion or operator+ that can be applied since char* is NOT a class.
Try this (changes marked in blue):
#include <windows.h>
#include <string>
using namespace std;
const char *ClsName = "BasicApp";
const char *WndName = "A Simple Window";
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg,
WPARAM wParam, LPARAM lParam);
INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MSG Msg;
HWND hWnd;
WNDCLASSEX WndClsEx;
// Create the application window
WndClsEx.cbSize = sizeof(WNDCLASSEX);
WndClsEx.style = CS_HREDRAW | CS_VREDRAW;
WndClsEx.lpfnWndProc = WndProc;
WndClsEx.cbClsExtra = 0;
WndClsEx.cbWndExtra = 0;
WndClsEx.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClsEx.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClsEx.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
WndClsEx.lpszMenuName = NULL;
WndClsEx.lpszClassName = ClsName;
WndClsEx.hInstance = hInstance;
WndClsEx.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
// Register the application
RegisterClassEx(&WndClsEx);
// Create the window object
hWnd = CreateWindow(ClsName,
WndName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);
// Find out if the window was created
if( !hWnd ) // If the window was not created,
return 0; // stop the application
// Display the window to the user
ShowWindow(hWnd, SW_SHOWNORMAL);
UpdateWindow(hWnd);
// Decode and treat the messages
// as long as the application is running
while( GetMessage(&Msg, NULL, 0, 0) )
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
int xPos = HIWORD(lParam);
int yPos = LOWORD(lParam);
if (Msg==WM_LBUTTONDOWN) {
char buf[20];
string str = "X = " + string(itoa(xPos,buf, 10)) + "\nY = " + string(itoa(yPos,buf, 10));
MessageBox(NULL, str.data() , "Mouse's Area", MB_OK);}
else if (Msg==WM_DESTROY) PostQuitMessage(WM_QUIT);
else return DefWindowProc(hWnd, Msg, wParam, lParam);
return 0;
}
Zachm at 2007-11-9 1:25:43 >

# 3 Re: The usual, whats wrong here?
Thanks for your post but I've never seen code like that before so as you can see I don't understand it, I will make an effort to understand your code but could you please tell me what this line does exactly -
int xPos = HIWORD(lParam);
int yPos = LOWORD(lParam);
Along with that I have an issue with the following code -
#include <windows.h>
using namespace std;
const char *ClsName = "BasicApp";
const char *WndName = "A Simple Window";
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg,
WPARAM wParam, LPARAM lParam);
INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MSG Msg;
HWND hWnd;
WNDCLASSEX WndClsEx;
// Create the application window
WndClsEx.cbSize = sizeof(WNDCLASSEX);
WndClsEx.style = CS_HREDRAW | CS_VREDRAW;
WndClsEx.lpfnWndProc = WndProc;
WndClsEx.cbClsExtra = 0;
WndClsEx.cbWndExtra = 0;
WndClsEx.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClsEx.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClsEx.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
WndClsEx.lpszMenuName = NULL;
WndClsEx.lpszClassName = ClsName;
WndClsEx.hInstance = hInstance;
WndClsEx.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
// Register the application
RegisterClassEx(&WndClsEx);
// Create the window object
hWnd = CreateWindow(ClsName,
WndName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);
// Find out if the window was created
if( !hWnd ) // If the window was not created,
return 0; // stop the application
// Display the window to the user
ShowWindow(hWnd, SW_SHOWNORMAL);
UpdateWindow(hWnd);
// Decode and treat the messages
// as long as the application is running
while( GetMessage(&Msg, NULL, 0, 0) )
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
if (Msg==WM_LBUTTONDOWN) LoadCursorFromFile("test.cur");
else if (Msg==WM_DESTROY) PostQuitMessage(WM_QUIT);
else return DefWindowProc(hWnd, Msg, wParam, lParam);
return 0;
}
All it does is start the program up and when I left click nothing happens(and yeah I did make sure the file was in the same folder and I also made sure it had a .cur extension).
Thanks.
# 4 Re: The usual, whats wrong here?
Those are your x and y coordinates.
In lay terms, you use HIWORD and LOWORD to access different 'areas'(the high-order and low-order) of lParam, which is a 32-bit value.
# 5 Re: The usual, whats wrong here?
Actually use ostringstream so:
std::ostringstream oss;
oss << "X = " << xPos << "\r\nY = " << yPos;
MessageBox( NULL, oss.str().c_str(), "Mouse's Area", MB_OK );
If you are using CString anyway in your project then you can alternatively do
CString msg;
msg.Format( "X = %d\r\nY=%d", xPos, yPos );
MessageBox( NULL, msg, "Mouse's Area", MB_OK ); // or msg.GetString()
# 6 Re: The usual, whats wrong here?
Thanks for your posts guys!
Greggle - Do you mind elaborating a little? I think I know what you mean but I'm not sure. Could you also explain how they are used?
I know I should use Google but I have homework that needs me :(
Thanks.
# 7 Re: The usual, whats wrong here?
As you wish...
lParam is a 32-bit value(under a Win32 environment). In your context it is simply two 16-bit values sandwiched together. In the low-word(LOWORD) it is the x-coordinate relative to the upper-left corner of the client area(your window). In the high-word(HIWORD) it is the y-coordinate.
You use the LOWORD and HIWORD macros to parse those values out of the lParam.
So, if you clicked right in the perfect center of your window, which is, say, 800x600, the lParam would be '400300', logically speaking.
LOWORD will yank out 400 and HIWORD, 300.
Having said that, you should move that code into your WM_LBUTTONDOWN(or whichever button you're using). It doesn't have to be there, but it's good form. The lParam(and wParam) will be different and do different things for each kind of message, so having that code right at the beginning of your WndProc isn't telling you much. It will still work, but there is no context.
# 8 Re: The usual, whats wrong here?
Thanks man that helped a lot!
But there's still something there that I just don't understand at this point. If you answer this question it may indirectly solve this other one - are wParam and iParam two parameters for certain functions?
questions -
1) What's the difference between hInstance and a handle(they're both used to track windows)?
2) Is there any other example of how to detect the click of a button(which just displays a MessageBox that says hello)?
3) How would you read input from edit box?
Thanks.
# 9 Re: The usual, whats wrong here?
1) hInstance is a handle itself, only it's a handle to the program as opposed to something like hWnd, which is a handle to a window of a program.
2) Too vague. There are a bajillion ways to click a 'button' and display a message box. The fact that you're clicking a 'button' is irrelevant(as far as the code is concerned); it's just another message.
I can't think of a simpler or more appropriate way than to call MessageBox(...) from your mouse-button-down events. Don't reinvent the wheel, pally.
3) GetWindowText(...)
# 10 Re: The usual, whats wrong here?
Replies -
1) What do you mean?
2) Please just put in the button window along with the code that should display a message box when the button is clicked.
3) Sorry for this but could you please just give me an example as MSDN is quite crappy at doing so.
Thanks!
# 11 Re: The usual, whats wrong here?
1) A handle is just a 32-bit(usually) number that refers to an object. The actual number is of no importance to you. It allows you access to the object's members and suchlike.
2) When you say 'button' are you referring to a push/command button or a mouse button?
3) Nope. I can't write(well, compile) Windows code on this computer. All linux, I'm afraid. There's not all that much going on with GetWindowText(...). Tinker with it. I bet you can find other examples outside of msdn for using it.
# 12 Re: The usual, whats wrong here?
1) But what is the main difference between the two handles?
2) I didn't even know there where two ways of doing it. I'm not sure, can I have examples of both please :)
3) In the following code I just don't know how to get the hInstance variable to the edit control - could you please help? -
#include <windows.h>
const char *ClsName = "BasicApp";
const char *WndName = "A Simple Window";
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg,
WPARAM wParam, LPARAM lParam);
INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MSG Msg;
HWND hWnd;
WNDCLASSEX WndClsEx;
// Create the application window
WndClsEx.cbSize = sizeof(WNDCLASSEX);
WndClsEx.style = CS_HREDRAW | CS_VREDRAW;
WndClsEx.lpfnWndProc = WndProc;
WndClsEx.cbClsExtra = 0;
WndClsEx.cbWndExtra = 0;
WndClsEx.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClsEx.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClsEx.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
WndClsEx.lpszMenuName = NULL;
WndClsEx.lpszClassName = ClsName;
WndClsEx.hInstance = hInstance;
WndClsEx.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
// Register the application
RegisterClassEx(&WndClsEx);
// Create the window object
hWnd = CreateWindow(ClsName,
WndName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);
// Find out if the window was created
if( !hWnd ) // If the window was not created,
return 0; // stop the application
// Display the window to the user
ShowWindow(hWnd, SW_SHOWNORMAL);
UpdateWindow(hWnd);
// Decode and treat the messages
// as long as the application is running
while( GetMessage(&Msg, NULL, 0, 0) )
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
HWND button = CreateWindow("EDIT",
"Write Stuff Here",
WS_CHILD,
0,
0,
300,
300,
NULL,
NULL,
hInstance,
NULL);
if (Msg==WM_LBUTTONDOWN) {
TCHAR szBuf[80];
GetWindowText(button, szBuf, 80);}
else if (Msg==WM_DESTROY) PostQuitMessage(WM_QUIT);
else return DefWindowProc(hWnd, Msg, wParam, lParam);
return 0;
}
Thanks.
# 13 Re: The usual, whats wrong here?
1) Nothing, other than one is a handle to the program itself and the other is a handle to a window.
I'm not sure what you're confused about. Umm, if your program has one window and one window only it may seem reasonable to think that the handle to the program and the handle to the program's main window are the same thing, but they are not.
2) What sort of 'action' are you wanting to pop up the messagebox? You can write a program that simply displays a message box without all of the code you have above; it just won't have much functionality.
3) Now we're cookin' with fire. In your CrateWindow(...) calll to create the control you need to change that first 'NULL' to 'hWnd'. That CreateWindow(...) call is creating a child window, whose parent is 'hWnd'. That CreateWindow(...) call needs to know who is going to own this window you're trying to draw. You're using NULL, which, as you've experienced, is probably doing nothing in the case of you're edit control.
When, in WinMain, you use 'NULL' in the call to CreateWindow(...) it's just fine as that implies a 'top-level' or 'main' window; you needn't know the handle to the desktop, which is where the 'main' or 'top-level' window would be drawn...
In that same call you need to modify your 'hInstance.' There are a few ways to do this. I think the simplest would be:
(HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE)
GetWindowLong(...) just retrieves info about a particular window, hWnd in this case.
Just cut-n-paste the above where you have 'hInstance' in your CreateWindow(...) call where you're trying to create the edit control.
Note: I'm drawing from memory and have no way to test my 'suggestions', so bear with me. This is all coming out stream-of-consciousness. The API has a few more tricks up its sleeve. If it doesn't work, we'll go elsewhere. We can even 'backdoor' through the lParam, but we'll cross that bridge only if necessary.
# 14 Re: The usual, whats wrong here?
1) I'm just confused about what handle does what, there's a HWND and a HINSTANCE right? I just need to understand what their separate/individual jobs are.
2) Now I see where I confused you. The main goal is for me is to find out how to know when a button is clicked on and the message box should be the result of me clicking the button(I mean the button has to do something right?). Its like saying -
if (button=1) { \\If "button" is clicked then do the following...
MessageBox(NULL, "You clicked a button!", "Button", MB_OK);}
3) What's wrong now -
#include <windows.h>
const char *ClsName = "BasicApp";
const char *WndName = "A Simple Window";
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg,
WPARAM wParam, LPARAM lParam);
INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MSG Msg;
HWND hWnd;
WNDCLASSEX WndClsEx;
// Create the application window
WndClsEx.cbSize = sizeof(WNDCLASSEX);
WndClsEx.style = CS_HREDRAW | CS_VREDRAW;
WndClsEx.lpfnWndProc = WndProc;
WndClsEx.cbClsExtra = 0;
WndClsEx.cbWndExtra = 0;
WndClsEx.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClsEx.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClsEx.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
WndClsEx.lpszMenuName = NULL;
WndClsEx.lpszClassName = ClsName;
WndClsEx.hInstance = hInstance;
WndClsEx.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
// Register the application
RegisterClassEx(&WndClsEx);
// Create the window object
hWnd = CreateWindow(ClsName,
WndName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);
// Find out if the window was created
if( !hWnd ) // If the window was not created,
return 0; // stop the application
// Display the window to the user
ShowWindow(hWnd, SW_SHOWNORMAL);
UpdateWindow(hWnd);
// Decode and treat the messages
// as long as the application is running
while( GetMessage(&Msg, NULL, 0, 0) )
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
HWND EC = CreateWindow("EDIT",
"Write Stuff Here",
WS_CHILD,
0,
0,
300,
300,
hWnd,
NULL,
(HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE),
NULL);
if (Msg==WM_LBUTTONDOWN) {
TCHAR szBuf[80];
GetWindowText(EC, szBuf, 80);}
else if (Msg==WM_DESTROY) PostQuitMessage(WM_QUIT);
else return DefWindowProc(hWnd, Msg, wParam, lParam);
return 0;
}
The edit control isn't there/visible.
Thanks(for your help!).
# 15 Re: The usual, whats wrong here?
Hmm, try adding this:
| WS_VISIBLE
to the right of where it says 'WS_CHILD' in your CreateWindow(...) where you're creating the control. Don't forget those pipes( | ).
Edit: Take that BS_PUSHBUTTON out. I got confused with another post. All apologies...
# 16 Re: The usual, whats wrong here?
Nothing worked. What do you think is wrong?
# 17 Re: The usual, whats wrong here?
Take that 'BS_PUSHBUTTON' out. See above edited post.
# 18 Re: The usual, whats wrong here?
I did and it still did not :(
# 19 Re: The usual, whats wrong here?
I'm so stupid. There is no way to process messages in your code, a foundation of the API. How did I not see that!?!
Paste this:
LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE :
HWND EC = CreateWindow("EDIT",
"Write Stuff Here",
WS_CHILD | WS_VISIBLE,
0,
0,
300,
300,
hWnd,
NULL,
(HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE),
NULL);
return 0;
case WM_DESTROY :
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, Msg, wParam, lParam);
}//This is the end of the program...
I got rid of that 'if' block; worry about that later. We need the window to be drawn before anything else.
I can't believe I forget the message switch. I'm embarrased...
# 20 Re: The usual, whats wrong here?
Wait, does your program display ~any~ window, be it the 'main' window or otherwise? I think DefWindowProc(...) can call BeginPaint(...) and EndPaint(...) without a WM_PAINT message, but I don't recall. You should have a WM_PAINT message anyway.
I have to get some sleep. I'm code-exhausted. This is my last offer for this evening/morning:
LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
RECT rect;
switch (message)
{
case WM_CREATE :
HWND EC = CreateWindow("EDIT",
"Write Stuff Here",
WS_CHILD | WS_VISIBLE,
0,
0,
300,
300,
hWnd,
NULL,
(HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE),
NULL);
return 0;
case WM_PAINT :
hdc = BeginPaint(hWnd, &ps); //So we can draw on the window
GetClientRect(hWnd, &rect); //Get the dimensions of the window
EndPaint(hWnd, &ps); //Done drawing
return 0;
case WM_DESTROY :
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, Msg, wParam, lParam);
}//This is the end of the program...
# 21 Re: The usual, whats wrong here?
Lol your code confused me so I just did something else and it worked(apparently I forgot about WM_CREATE) -
#include <windows.h>
const char *ClsName = "BasicApp";
const char *WndName = "A Simple Window";
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg,
WPARAM wParam, LPARAM lParam);
INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MSG Msg;
HWND hWnd;
WNDCLASSEX WndClsEx;
// Create the application window
WndClsEx.cbSize = sizeof(WNDCLASSEX);
WndClsEx.style = CS_HREDRAW | CS_VREDRAW;
WndClsEx.lpfnWndProc = WndProc;
WndClsEx.cbClsExtra = 0;
WndClsEx.cbWndExtra = 0;
WndClsEx.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClsEx.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClsEx.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
WndClsEx.lpszMenuName = NULL;
WndClsEx.lpszClassName = ClsName;
WndClsEx.hInstance = hInstance;
WndClsEx.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
// Register the application
RegisterClassEx(&WndClsEx);
// Create the window object
hWnd = CreateWindow(ClsName,
WndName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);
// Find out if the window was created
if( !hWnd ) // If the window was not created,
return 0; // stop the application
// Display the window to the user
ShowWindow(hWnd, SW_SHOWNORMAL);
UpdateWindow(hWnd);
// Decode and treat the messages
// as long as the application is running
while( GetMessage(&Msg, NULL, 0, 0) )
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
HWND EC;
if (Msg==WM_CREATE) {
EC = CreateWindow("EDIT",
"Write stuff here",
WS_CHILD | WS_VISIBLE | ES_MULTILINE,
0,
0,
300,
300,
hWnd,
NULL,
(HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE),
NULL);}
else if(Msg==WM_LBUTTONDOWN) {
TCHAR szBuf[80];
GetWindowText(EC, szBuf, 80);
MessageBox(hWnd, szBuf, "You typed -", MB_OK);}
else if (Msg==WM_DESTROY) PostQuitMessage(WM_QUIT);
else return DefWindowProc(hWnd, Msg, wParam, lParam);
return 0;
}
Though I still don't know how to work with buttons. :(
Thanks.
# 22 Re: The usual, whats wrong here?
Awesome! And really, all apologies for not being able to get you working code the first time. I'll have Windows back soon enough.
In that interim, change your code back to the switch-case style. This is how it's done and anyone looking at your code later will thank you for it. Yeah, if you're only processing one or two messages an 'if' is alright, but when you're processing many the code becomes inefficient as it has to trudge through each and every 'if' until it satisfies its needs. That's wasteful.
Also, it is very rare for a window procedure to not process WM_PAINT messages; you need that case, too.
LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
RECT rect;
switch (Msg)
{
case WM_CREATE :
HWND EC = CreateWindow("EDIT",
"Write Stuff Here",
WS_CHILD | WS_VISIBLE,
0,
0,
300,
300,
hWnd,
NULL,
(HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE),
NULL);
return 0;
case WM_PAINT :
BeginPaint(hWnd, &ps);
GetClientRect(hWnd, &rect);
EndPaint(hWnd, &ps);
return 0;
case WM_DESTROY :
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, Msg, wParam, lParam);
}//This is the end of the program...
The switch-case from previously may not have worked because I used 'message' as the variable to test instead of 'Msg'. Surely your compiler barfed up an 'undeclared identifier' or something similar.
# 23 Re: The usual, whats wrong here?
To start with I thank you for your support!
And really, all apologies for not being able to get you working code the first time.
Its alright, it might not seem like it but you taught me a lot and from that I got the code to work :)
The switch-case from previously may not have worked because I used 'message' as the variable to test instead of 'Msg'. Surely your compiler barfed up an 'undeclared identifier' or something similar.
Reply With Quote
Lol, I am not the type who simply copies then pastes, I simply copied the part that seemed relevant :)
Questions -
1) I have some experience with the WM_PAINT message but why do I need to use it right now? What does that code do?
2) Although I have experience I think I should still go over it, so is it OK with you if I ask you to teach me all the basics for painting?
Thanks.
# 24 Re: The usual, whats wrong here?
1) I have some experience with the WM_PAINT message but why do I need to use it right now? What does that code do?
Well, nothing now, but what good is a window if you can't draw on it? I mean, if you just want to display a message box why not do this:
int WINAPI WinMain(HINSTANCE, hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, intiCmdShow)
{
MessageBox (NULL, TEXT ("Hello, World!"), TEXT ("Title Goes Here"), 0);
return 0;
}
Bam. That's an entire program. It's not doing much, but drawing an entire window with a white background that sits idly is not doing much either. But the instant you want to do something, like textual output, you're gonna need to be able to draw on the window.
You can certainly ask me questions, but it would take a prohibitive amount of time to go over every last detail of drawing and painting. And it's not like I've 'mastered' Win32 API programming anyway.
To make matters worse, like I've said before, I don't have a Windows environment to code in. That's a killer.
# 25 Re: The usual, whats wrong here?
What the heck is wrong with me! -
#include <windows.h>
const char *ClsName = "BasicApp";
const char *WndName = "A Simple Window";
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg,
WPARAM wParam, LPARAM lParam);
INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MSG Msg;
HWND hWnd;
WNDCLASSEX WndClsEx;
// Create the application window
WndClsEx.cbSize = sizeof(WNDCLASSEX);
WndClsEx.style = CS_HREDRAW | CS_VREDRAW;
WndClsEx.lpfnWndProc = WndProc;
WndClsEx.cbClsExtra = 0;
WndClsEx.cbWndExtra = 0;
WndClsEx.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClsEx.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClsEx.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
WndClsEx.lpszMenuName = NULL;
WndClsEx.lpszClassName = ClsName;
WndClsEx.hInstance = hInstance;
WndClsEx.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
// Register the application
RegisterClassEx(&WndClsEx);
// Create the window object
hWnd = CreateWindow(ClsName,
WndName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);
// Find out if the window was created
if( !hWnd ) // If the window was not created,
return 0; // stop the application
// Display the window to the user
ShowWindow(hWnd, SW_SHOWNORMAL);
UpdateWindow(hWnd);
// Decode and treat the messages
// as long as the application is running
while( GetMessage(&Msg, NULL, 0, 0) )
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
HWND EC;
switch (Msg) {
case WM_CREATE :
EC = CreateWindow("EDIT",
"Write stuff here",
WS_CHILD | WS_VISIBLE | ES_MULTILINE | ES_CENTER,
0,
0,
300,
300,
hWnd,
NULL,
(HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE),
NULL);
break;
case WM_LBUTTONDOWN :
TCHAR szBuf[80];
GetWindowText(EC, szBuf, 80);
MessageBox(hWnd, szBuf, "You typed -", MB_OK);
break;
case WM_DESTROY :
PostQuitMessage(WM_QUIT);
break;
}
return DefWindowProc(hWnd, Msg, wParam, lParam);
}
For some reason I forgot that the main idea doesn't work; when I do left click on the window the messagebox comes up but has nothing written in it, what's wrong?
Bam. That's an entire program.
I guess that there is still an mis-understanding, I just want to know how to detect when a user clicks a button, I don't really care about the message-box itself but like I said I just want to know how to tell if the user clicks a button and thats it(by the way you just used a Linux MessageBox :)).
You can certainly ask me questions, but it would take a prohibitive amount of time to go over every last detail of drawing and painting. And it's not like I've 'mastered' Win32 API programming anyway.
Can you really blame me for thinking you're very good(complement :))? By the way I said the basics is what I want/need to learn.
questions -
1) Apart from the ones I've already asked, how do you work with sound? May I have an example in which a simple file called file.(extension) is played from the program's main directory?
Thanks (I really appreciate it)!
# 26 Re: The usual, whats wrong here?
1) Is there anything written in the caption bar?
At first glance it would appear that nothing is being displayed in the message box because you haven't given it anything to display.
You never initialize or otherwise assign a string to 'szBuf', so it's no wonder nothing is being displayed. 'szBuf' is an empty string! You can use a string literal there if you like, just like you did for the caption.
2) You've figured it out. WM_LBUTTONDOWN is doing just that.
3) PlaySound("some_file_name.extension", NULL, SND_FILENAME);
Look that up so you know what's going on. It's a simple function.
# 27 Re: The usual, whats wrong here?
The following code doesn't play sound(defined under the WM_RBUTTONDOWN message) and doesn't display the text in the message box eighter(WM_LBUTTONDOWN) -
#include <windows>
const char *ClsName = "BasicApp";
const char *WndName = "A Simple Window";
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg,
WPARAM wParam, LPARAM lParam);
INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MSG Msg;
HWND hWnd;
WNDCLASSEX WndClsEx;
// Create the application window
WndClsEx.cbSize = sizeof(WNDCLASSEX);
WndClsEx.style = CS_HREDRAW | CS_VREDRAW;
WndClsEx.lpfnWndProc = WndProc;
WndClsEx.cbClsExtra = 0;
WndClsEx.cbWndExtra = 0;
WndClsEx.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClsEx.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClsEx.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
WndClsEx.lpszMenuName = NULL;
WndClsEx.lpszClassName = ClsName;
WndClsEx.hInstance = hInstance;
WndClsEx.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
// Register the application
RegisterClassEx(&WndClsEx);
// Create the window object
hWnd = CreateWindow(ClsName,
WndName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);
// Find out if the window was created
if( !hWnd ) // If the window was not created,
return 0; // stop the application
// Display the window to the user
ShowWindow(hWnd, SW_SHOWNORMAL);
UpdateWindow(hWnd);
// Decode and treat the messages
// as long as the application is running
while( GetMessage(&Msg, NULL, 0, 0) )
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
HWND EC;
switch (Msg) {
case WM_CREATE :
EC = CreateWindow("EDIT",
"Write stuff here",
WS_CHILD | WS_VISIBLE | ES_MULTILINE | ES_CENTER,
0,
0,
300,
300,
hWnd,
NULL,
(HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE),
NULL);
break;
case WM_LBUTTONDOWN :
char szBuf[80];
GetWindowText(EC, szBuf, 80);
MessageBox(hWnd, szBuf, "You typed -", MB_OK);
break;
case WM_RBUTTONDOWN :
PlaySound("file.wma", NULL, SND_FILENAME);
break;
case WM_DESTROY :
PostQuitMessage(WM_QUIT);
break;
}
return DefWindowProc(hWnd, Msg, wParam, lParam);
}
When I right click on my program it just makes a beep and that's it. And I'm sure I have given szBuf a value; that's what GetWindowText is doing right?
1) Nothing but the title(its a constant).
2) Doing what?
3) I tried it but it didn't work :(
Thanks.
# 28 Re: The usual, whats wrong here?
Umm. People needed, will pay :).
# 29 Re: The usual, whats wrong here?
1) I don't know what to tell you. The GetWindowText function's default behavior is to retrieve the caption from a window unless it's a control, which, in this case, it is. But it's obviously retrieving the caption from your main window.
2) I've only gotten PlaySound(...) in Windows IDEs. 'Got me there, too.
# 30 Re: The usual, whats wrong here?
To start with how comes you're the only person helping me here? I'm sure a lot of other people know how to do it as this action(retrieving input) is quite common.
Question and answers -
1) Actually no caption/text is being retrieved :(
2) What do you mean by got me there. too?
3) How do I create Context Menus?
4) How do I minimize my program to the bottom right area(Notification area)?
5) Is it possible to draw to the desktop itself(after all it is a program; explorer.exe)?
I did use Google.
Thanks.
# 31 Re: The usual, whats wrong here?
I mean I don't know how to help you with the PlaySound. I've used it only once.
'Don't know about context menus or getting a program into the tray either.
And I'm not entirely sure what you mean in your last question.
# 32 Re: The usual, whats wrong here?
By last question I simply mean can you draw directly on the desktop?
# 33 Re: The usual, whats wrong here?
Oh, I'm sure there's some way to, but I can't see why you would want to.
Also, try posting in the Win32 API forum. That's what we're talking about, afterall.
# 34 Re: The usual, whats wrong here?
Lol, I sort of realized that after the first page :)
Do you know where I may learn those things I listed?
Thanks.
# 35 Re: The usual, whats wrong here?
Alright, try GetDlgItemText(...) in your WM_LBUTTONDOWN. Supply the handle to the parent window.
You'll also have to define an ID for the control. Somewhere at the top of your code(I usually do this right after my 'includes') put in something like:
#define ID_EDIT 1
You can choose the name and number arbitrarily. The important thing is that they are unique. All caps and underscores are convention, but not enforced.
In your CreateWindow(...) function for the edit control, the ninth(the 'menu' one) parameter needs to read:
(HMENU)ID_EDIT
Of course, if you choose a different name you'll need to reflect that in the CreateWindow(...) call for your edit control.
# 36 Re: The usual, whats wrong here?
But I'm not working with Dialogs. I'm working with the CreateWindowEx function...
# 37 Re: The usual, whats wrong here?
Doesn't matter.
# 38 Re: The usual, whats wrong here?
Hmm, I'm quite confused. Please just edit the following code -
#include <windows>
const char *ClsName = "BasicApp";
const char *WndName = "A Simple Window";
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg,
WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MSG Msg;
HWND hWnd;
WNDCLASSEX WndClsEx;
// Create the application window
WndClsEx.cbSize = sizeof(WNDCLASSEX);
WndClsEx.style = CS_HREDRAW | CS_VREDRAW;
WndClsEx.lpfnWndProc = WndProc;
WndClsEx.cbClsExtra = 0;
WndClsEx.cbWndExtra = 0;
WndClsEx.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClsEx.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClsEx.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
WndClsEx.lpszMenuName = NULL;
WndClsEx.lpszClassName = ClsName;
WndClsEx.hInstance = hInstance;
WndClsEx.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
// Register the application
RegisterClassEx(&WndClsEx);
// Create the window object
hWnd = CreateWindow(ClsName,
WndName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);
// Find out if the window was created
if( !hWnd ) // If the window was not created,
return 0; // stop the application
// Display the window to the user
ShowWindow(hWnd, SW_SHOWNORMAL);
UpdateWindow(hWnd);
// Decode and treat the messages
// as long as the application is running
while( GetMessage(&Msg, NULL, 0, 0) )
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
HWND EC;
switch (Msg) {
case WM_CREATE :
EC = CreateWindow("EDIT",
"Open Edit Window",
WS_CHILD | WS_VISIBLE | ES_MULTILINE,
0,
0,
140,
20,
hWnd,
NULL,
(HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE),
NULL);
break;
case WM_DESTROY :
PostQuitMessage(WM_QUIT);
break;
}
return DefWindowProc(hWnd, Msg, wParam, lParam);
}
Thanks.
# 39 Re: The usual, whats wrong here?
No way, pally. You are your own best teacher.
I've already told you what to do and where to put it. I haven't told you how to implement the GetDlgItemText(...) because you can find its signature online pretty easily. It's a simple function, like MessageBox(...)
Also, I see no calls to CreateWindowEx(...). If that were the case there's, like, one extra parameter.
Anyway, look up the signature to CreateWindow(...) and look for the parameter that says something to the effect of hMenu. That is where you will put what I listed previously in your call to CreateWindow(...) for the edit control.
# 40 Re: The usual, whats wrong here?
Grrr, whats wrong now? -
#include <windows>
#define ID_EDIT 113
const char *ClsName = "BasicApp";
const char *WndName = "A Simple Window";
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg,
WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MSG Msg;
HWND hWnd;
WNDCLASSEX WndClsEx;
// Create the application window
WndClsEx.cbSize = sizeof(WNDCLASSEX);
WndClsEx.style = CS_HREDRAW | CS_VREDRAW;
WndClsEx.lpfnWndProc = WndProc;
WndClsEx.cbClsExtra = 0;
WndClsEx.cbWndExtra = 0;
WndClsEx.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClsEx.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClsEx.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
WndClsEx.lpszMenuName = NULL;
WndClsEx.lpszClassName = ClsName;
WndClsEx.hInstance = hInstance;
WndClsEx.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
// Register the application
RegisterClassEx(&WndClsEx);
// Create the window object
hWnd = CreateWindow(ClsName,
WndName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);
// Find out if the window was created
if( !hWnd ) // If the window was not created,
return 0; // stop the application
// Display the window to the user
ShowWindow(hWnd, SW_SHOWNORMAL);
UpdateWindow(hWnd);
// Decode and treat the messages
// as long as the application is running
while( GetMessage(&Msg, NULL, 0, 0) )
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
HWND EC;
switch (Msg) {
case WM_CREATE :
EC = CreateWindow("EDIT",
"Open Edit Window",
WS_CHILD | WS_VISIBLE,
0,
0,
140,
20,
hWnd,
(HMENU)ID_EDIT,
(HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE),
NULL);
break;
case WM_LBUTTONDOWN :
char text[80];
GetDlgItemText(113, text, 80)
MessageBox(hWnd, text, "Recorded Text", MB_OK);
break;
case WM_DESTROY :
PostQuitMessage(WM_QUIT);
break;
}
return DefWindowProc(hWnd, Msg, wParam, lParam);
}
Thanks.
# 41 Re: The usual, whats wrong here?
You haven't supplied an hWnd parameter. Check GetDlgItemText's signature on MSDN again.
Also, use the name of the named constant and not the value. Either will work, but it's good practice to use the name as it is more meaningful than '113'.