Does any one or can any one help me with handling messages?

Pages: 12
Okay, my problem is likely some thing most Windows API users can handle....Or could figure out before me.

If I may ask, how may I or might you give me tips or advice on how I can get a Windows API program(one from a C++ builder)to catch and translate a message such as a click and then get it to write text on the screen?

Like, to be even more specific, I want to be able to click on the screen and have the text appear, but not sure how to with the slight confusion on message handling and the clicking handling.

Here's the best code I can think of, as wrong as it may be:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include <windows.h>
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
char szClassName[ ] = "WindowsApp";
int WINAPI WinMain (HINSTANCE hThisInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR lpszArgument,
                    int SHOW)
{
    HWND hwnd;              
    MSG messages;           
    WNDCLASSEX wincl;       
    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;     
    wincl.style = CS_DBLCLKS;                
    wincl.cbSize = sizeof (WNDCLASSEX);
    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;                
    wincl.cbClsExtra = 0;                   
    wincl.cbWndExtra = 0;                      
    wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
    if (!RegisterClassEx (&wincl))
        return 0;
    hwnd = CreateWindowEx (
           0,                   
           szClassName,        
           "Windows App",       
           WS_OVERLAPPEDWINDOW, 
           CW_USEDEFAULT,       
           CW_USEDEFAULT,      
           544,                
           375,              
           HWND_DESKTOP,    
           NULL,               
           hThisInstance,     
           NULL                
           );
    ShowWindow (hwnd, SHOW);
    while (GetMessage (&messages, NULL, 0, 0))
    {
        TranslateMessage(&messages);
        DispatchMessage(&messages);
    }
    return messages.wParam;
}
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    while(1)
    {
    bool DO = 0;
    switch (message)               
    {
        case WM_LBUTTONDOWN:
             if(DO == 0)
             {
              DO = 1;
                   }
             break;
        case WM_DESTROY:
            PostQuitMessage (0);      
            break;
        case WM_PAINT:
        if(DO == 1)
        {
        HDC hdc;
        PAINTSTRUCT PAINT;
        hdc = BeginPaint(hwnd, &PAINT);
        TextOut(hdc, 0, 0, "I clicked!", 10);
        EndPaint(hwnd, &PAINT);
        }
        else{break;}
        default:                       
            return DefWindowProc (hwnd, message, wParam, lParam); 
    }
}

    return 0;
}


EVERY time I run the program it begins to not respond and have to reset it, but the while loop is the only way I can think of for a logical way of it catching a click and enabling it to paint from that click by setting a bool from false to true and repeating the loop for it to test if it should paint whether or not it's true or false. Get it?
It seems you didn't quite understand how the window procedure works. The window procedure is called everytime a new message arises, so your while loop really doesn't do anything other than crashing the program.

What you really want to do is to have something that can store x and y coordinates (global ints for starters), and then when you catch a WM_LBUTTONDOWN message, you set x to LOWORD(lParam) and y to HIWORD(lParam), and then call InvalidateRect(hWnd, NULL, TRUE). In the WM_PAINT handler, you replace TextOut(hdc, 0, 0, "I clicked!", 10) by TextOut(hdc, x, y, "I clicked!", 10)

EDIT: damn, fell for it. Whatever, I leave the response here, maybe someone who actually needs help will come here.
Last edited on
Your description isn't explained well-enough....
EDIT: damn, fell for it. Whatever, I leave the response here, maybe someone who actually needs help will come here.


I laughed. XD
Stop trolling and give me some advice! >X<
Spoon licker, you're on pretty poor terms with most of the forum members here (including me). If you want advice, you'll need to prove to us that you won't react to us the same way you did when we gave you some pretty decent explanations about pointers. :/

-Albatross
Okay, I promise I won't be too mean like before. Although your pointer explanations were nothing "epic" of teaching....Not being mean, but they weren't the best I've heard.
Last edited on
Well since you're so dissatisfied with our attempts to help, perhaps you should just go away and never come back.
Perhaps you should improve your attempts to help? :P
Perhaps you should improve your attempts to help?

The way you phrased that statement, there's no way you aren't trying to get even a small reaction. Aw... and there I was hoping you were going to consider giving up that path.

I must say, though, this is your most respectful behavior on this forum yet. I really shouldn't give you a warning at all, but here it is: one calm warning. That's the only one you'll get for your current account, but because you seem to be behaving MUCH harder than the last few times, I'll withhold my post-deleting reports for this minor offense.

-Albatross
spoon licker wrote:
Perhaps you should improve your attempts to help? :P


I apologize if my teachings were sub-par. You can bet that I will do my best to help. Even if you are trolling.

edit: 400 =)
Last edited on
closed account (z05DSL3A)
spoon licker,
See: Learn to Program for Windows in C++
http://msdn.microsoft.com/en-us/library/ff381399(v=VS.85).aspx
That MSDN is not good enough. It's not 100% thorough and informative on exactly how to use all of the functions with well-documented logic and use with C++.

Besides, I already can program with Windows, I just need some help improving on it and MSDN.com doesn't give me that help...
Last edited on
closed account (z05DSL3A)
Besides, I already can program with Windows

This and other threads suggest not.

If the documentation written by the company that created Windows is not thorough enough for you, then I am at a loss as to what would be. All suggestions that have been given are not good enough, so...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	static int x = 0, y = 0;

    switch (message)               
    {
        case WM_LBUTTONDOWN:
			x = LOWORD(lParam);
			y = HIWORD(lParam);
			InvalidateRect(hwnd, 0, TRUE);
            break;
        case WM_DESTROY:
            PostQuitMessage (0);      
            break;
        case WM_PAINT:
		{
			HDC hdc;
			PAINTSTRUCT PAINT;
			hdc = BeginPaint(hwnd, &PAINT);
			
			const char *text = "I clicked!";
			TextOut(hdc, x, y, text, strlen(text));
			
			EndPaint(hwnd, &PAINT);
        }
	}
    return DefWindowProc (hwnd, message, wParam, lParam);
}


try that. wm_paint is called each time the window is sized or overlapped. but if you call InvalidateRect, it will force it to send wm_paint.

gl

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static int x = 0, y = 0;

switch (message)
{
case WM_LBUTTONDOWN:
x = LOWORD(lParam);
y = HIWORD(lParam);
InvalidateRect(hwnd, 0, TRUE);
break;
case WM_DESTROY:
PostQuitMessage (0);
break;
case WM_PAINT:
{
HDC hdc;
PAINTSTRUCT PAINT;
hdc = BeginPaint(hwnd, &PAINT);

const char *text = "I clicked!";
TextOut(hdc, x, y, text, strlen(text));

EndPaint(hwnd, &PAINT);
}
}
return DefWindowProc (hwnd, message, wParam, lParam);
}


try that. wm_paint is called each time the window is sized or overlapped. but if you call InvalidateRect, it will force it to send wm_paint.

gl


Well, bro, I can thank you a LOT for that tip, but it's not what I wanted.

See, I wanted it to be drawn to the window when I click, and although that code puts the text exactly where you click it automatically draws it before you do once the window is created.

Although it's still pretty much what I wanted, it's not what I said I wanted....Which was for the text to ONLY appear when you click and not appear before.
Last edited on
Also, you can forget the rest if you want. I really do appreciate the help, previous poster of the code.

If you're willing to be nice one more time, mind telling me how to draw a bitmap to the window?
That's a more difficult one.

Here's some code that works, please check what it does and adjust for your needs.

*bitdata = RGB bit data (1 32-bit value per pixel)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
void PlempOnScreen(HDC hdc, int bits_per_pixel, HWND hwnd, int *bitdata, int pos_x, int pos_y, int width, int height)
{
    BITMAPINFO* m_pBitmapInfo;   // class member

    int i;

    BITMAPINFO bmi;

    bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    bmi.bmiHeader.biWidth = width;
    bmi.bmiHeader.biHeight = -height;  // if negative, image is mirrored along y-axis
    bmi.bmiHeader.biPlanes = 1;
    bmi.bmiHeader.biBitCount = 32;
    bmi.bmiHeader.biCompression  = BI_RGB;
    bmi.bmiHeader.biSizeImage = 0;
    bmi.bmiHeader.biXPelsPerMeter = 0;
    bmi.bmiHeader.biYPelsPerMeter = 0;
    bmi.bmiHeader.biClrUsed = 0;
    bmi.bmiHeader.biClrImportant = 0;

    try
    {
        SetDIBitsToDevice(
            hdc,//dc->GetSafeHdc(),
            pos_x,
            pos_y,
            width,
            height,
            0,
            0,
            0,//__in  UINT uStartScan,
            height,//__in  UINT cScanLines,
            bitdata,
            &bmi,
            DIB_RGB_COLORS);
    }
    catch (...)
    {
    }
}



You need a HDC. To get one, do something like this:
1
2
3
4
5
6
7
8
9
           CWnd *cwnd = CWnd::FromHandle(my_hwnd);

           if (cwnd != NULL)
           {
	           CClientDC dc(cwnd);
    	       CDC bmDC;
               bmDC.CreateCompatibleDC(&dc);
               HDC hdc = dc.GetSafeHdc();
           }



Note: This is not the best possible code, it only works at 32 bit displays...
Last edited on
closed account (ywv4jE8b)
No doubt it's not the best possible code....It makes nary sense to me even reading it 100 times in a row and reading MSDN tutorials.

Um....How exactly does that code even load a bitmap from a resource on the hard drive?

None of the code you gave mentions or hints that, so I'm gonna go on a limb and say that the code is wrong.

EDIT: I actually compiled the code and it works although I have no clue on how to specify the bitmap I want loaded(your code doesn't make sense enough for me to figure out how to do that).

That's pretty much the whole question I was asking, which is HOW and WHERE and WHAT to do to specify the bitmap and the process of how to put it in the window.

And as much as I hate using try , can't it be spared for some thing else?
Last edited on
You can't be arrogant and ignorant at the same time. In the end, no one will help you.
Pages: 12