Going over the Windows Programming Code...

Pages: 123
Why is there a _T in the code for?
The ampersand symbol '&' goes right before the letter you want to be able to be actuated with the [ALT][whatever key] sequence.

_T is a macro that keys off of whether UNICODE is defined or not. You really need to do a search for UNICODE and TCHAR and study up hard on that before you do one more thing. Its that important. I have a little write up on it here ...

http://www.jose.it-berater.org/smfforum/index.php?topic=3389.0
long __stdcall fnWndProc(HWND hwnd, unsigned int msg, WPARAM wParam, LPARAM lParam)

Does this line create a text box or window? I searched on Google and those were the options.
Nevermind. A little more research and I found that LRESULT was a long. LRESULT CALLBACK WndProc(...) can be written as long __stdcall fnWndProc(...) -- I tried it and it worked.
You shouldn't have seen that long __stdcall stuff. I had inadvertantly posted that in one of the programs and I edited what I posted later when I saw it was there. You must have copied that before I fixed it, as I just looked and you won't find that in any of the posts in this thread (because, like I said, I fixed it by editing).

What had happened is that I needed a demo program quick to post for another member here whose question was about the CALLBACK keyword. That word is an 'equate' or #define from, among other places, Windef.h, one of the Windows header files. 32 bit Windows and the x86 processors allow several different stack setups in terms of calling functions, and one of them is standard call ( __stdcall ). This one is a bit different from the standard stack setup C uses, which is __cdecl. So that's all that was about. When I posted the next series of programs for you I had forgotten to replace the long __stdcall with LRESULT CALLBACK. Then I saw it and fixed it, but you inadvertantly still had the bad code, which, however, runs fine on a 32 bit compile. It won't work on a 64 bit compile though. I'm sorry I threw you that twist. I see you invested a little work and figured it out though. That's good!
It's ok. I recopied this particular code because I was looking over the code, deleting some, keeping some, seeing what each line did and when I closed out of my window, it saved when I told it not to save and when I pulled it back up, only half the code was there.


In my search for LRESULT, I figured out stdcall and stuff, but I didn't figure out why is it called long and what its use for is in the program; the same with stdcall. I wish there was (not saying there isn't, just haven't found one yet) a reference site for C++ like w3school.com. That's a good learning site when wanting to learn web code.

I wish there was (not saying there isn't, just haven't found one yet) a reference site for C++ like w3school.com.


One thing you might be confusing in your mind is that you likely won't get much help about this stuff from C++ oriented sites. The reason for that is that this material and the struggles you are going through aren't very much related to C++. C++ is simply one of many possible languages you could use to interface with the Windows Api. Most folks who've learned this style of programming learned it from Charles Petzold's "Programming Windows" books. It just so happens that Charles used C in his books, but his books weren't books on C or C++ or that made any attempt to teach C or C++. He simply used C because that is pretty much the standard in professional level systems programming.

What he taught was how to interface with the Windows Api using C, and what the program architecture had to look like to create a GUI Windows program using its Api. One of the central concepts there is the 'Window Procedure'. Its a __stdcall function which Windows calls to inform your program that the user or OS has information you need to know about. It 'sends' messages to the Window Procedure. You tell Windows the function you want it to call by giving it the address of a function in the program, and that function is the Window Procedure, or fnWndProc() in my code I gave you. The function takes four parameters and in 32 bit Windows returns a long. It is a __stdcall function as opposed to __cdecl (standard for C/C++).

I might point out that folks using other programming languages besides C/C++ use Petzold's book to learn Windows Programming, because its done very similiarly in other languages. Here is a Windows Program written in PowerBASIC, which is another very high performance language I use which is a fast as C and in most cases produces much smaller executables. You should recognize it ...

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
'Compiles to 6K exe
#Compile Exe 
#Include "Windows.inc"

Function WndProc(ByVal hWnd As Long,ByVal wMsg As Long,ByVal wParam As Long,ByVal lParam As Long) As Long
  If wMsg=%WM_DESTROY Then
     Call PostQuitMessage(0)
     WndProc=0
     Exit Function
  End If

  WndProc=DefWindowProc(hWnd,wMsg,wParam,lParam)
End Function

Function WinMain(ByVal hIns As Long,ByVal hPrevIns As Long,ByVal lpCmdLine As Asciiz Ptr,ByVal iShow As Long) As Long
  Local szClassName As Asciiz*6
  Local wc As WndClassEx
  Local hWnd As Dword
  Local Msg As tagMsg

  szClassName             ="Form1"
  wc.lpszClassName        =VarPtr(szClassName)
  wc.lpfnWndProc          =CodePtr(WndProc)
  wc.cbSize               =SizeOf(wc)
  wc.hInstance            =hIns
  RegisterClassEx(wc)
  hWnd=CreateWindowEx(0,szClassName,szClassName,%WS_OVERLAPPEDWINDOW,200,100,325,300,%HWND_DESKTOP,0,hIns,ByVal 0)
  ShowWindow(hWnd,iShow)
  While GetMessage(Msg,%NULL,0,0)
    Call TranslateMessage(Msg)
    Call DispatchMessage(Msg)
  Wend

  WinMain=msg.wParam
End Function 


Here is the same exact program in C/C++ ...

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
//Compiles to about 7K
#include <windows.h>

LRESULT CALLBACK fnWndProc(HWND hwnd, unsigned int msg, WPARAM wParam,LPARAM lParam)
{
 if(msg==WM_DESTROY)
 {
    PostQuitMessage(0);
    return 0;
 }

 return (DefWindowProc(hwnd, msg, wParam, lParam));
}


int WINAPI WinMain(HINSTANCE hIns, HINSTANCE hPrevIns, LPSTR lpszArgument, int iShow)
{
 char szClassName[]="Form1";
 WNDCLASSEX wc={};
 MSG messages;
 HWND hWnd;

 wc.lpszClassName   = szClassName;
 wc.lpfnWndProc     = fnWndProc;
 wc.cbSize          = sizeof (WNDCLASSEX);
 wc.hInstance       = hIns;
 RegisterClassEx(&wc);
 hWnd=CreateWindowEx(0,szClassName,szClassName,WS_OVERLAPPEDWINDOW,100,100,350,300,HWND_DESKTOP,0,hIns,0);
 ShowWindow(hWnd,iShow);
 while(GetMessage(&messages,NULL,0,0))
 {
    TranslateMessage(&messages);
    DispatchMessage(&messages);
 }

 return messages.wParam;
}              


So you see, where you are stuck isn't C++, but rather the program architecture of Windows. If you don't get Petzold's book, your next best bet are Win32 Api tutorials, and MSDN. If you type the name of any Windows Api function such as CreateWindowEx into your browser Search function, it'll lead you to MSDN documentation on that. The reason I'm taking the time to help you with this is because I can see you are really trying.
Last edited on
Its a __stdcall function which Windows calls to inform your program that the user or OS has information you need to know about.


What am I calling and how would I do it?

Is this like the <iostream> or stdafx.h? I related what you wrote to taking code from, say, the stdafx.h -- it puts or includes code from that file into your program. Is it the same concept?
Its a __stdcall function which Windows calls to inform your program that the user or OS has information you need to know about. It 'sends' messages to the Window Procedure. You tell Windows the function you want it to call by giving it the address of a function in the program, and that function is the Window Procedure, or fnWndProc()....


I took a sneak peek at the Programming Windows book on Amazon and one thing I did notice was he went over the 'arguments' which I discovered...

long __stdcall fnWndProc(HWND hwnd, unsigned int msg, WPARAM wParam, LPARAM lParam)


It reads right to left -- (HWND hwn, unsigned int msg.....) this is the argument, and I needed help on the argument, calling convention and result-type. I'll try out the Wind32 API tutorials and MSDN.

I do appreciate your help. It's very helpful.
Why is it called an argument? ((HWND hwnd, unsigned int msg, WPARAM wParam, LPARAM lParam))

What am I calling and how would I do it?


You call nothing, ever. Only Windows the operating system calls the Window Procedure. That WNDPROC function is for Windows use only. You never call it directly.

A pretty good tutorial you should look at is the Forger's Win32 Tutorial. Do a search on that term and you will find it. Most folks here recommend it. I've already given you a link to a tutorial I've written. Its on a slightly higher level of abstraction, possibly. If you spent a couple hours with each of those you would get a pretty good idea wha's going on. I repeat studying C++ will not help. You could memorize the entire C++ language standard, and read every C++ book ever written, and it wouldn't help yu understand the architecture of a Windows program, as it is an entirely different topic.

Windows programs use an architecture known as 'event driven' or 'message driven'. This is entirely different from a console program.

In the Windows architecture, you specify the general characteristics of a 'class' by allocating a WNDCLASSEX object. There are quite a few fields in the WNDCLASSEX object, but the two most important are the WNDCLASSEX::szClassName field, and the WNDCLASSEX::lpfnWndProc fields. The szClassName field is important because it is the textural name by which Windows will recognize the class name of the object you wish to instantiate through a CreateWindowEx() function call, which call creates an instance of the szClassName object.

The WNDCLASSEX::lpfnWndProc member is an address, such as 1234567. It needs to be the address of a valid Window Procedure in your program. The Window Procedure must have an exact and unvarying function signature, in that it must return an LRESULT, be a standard call function as opposed to a C Declension function ( __cdecl ), and must have four integral parameters, i.e., HWND, which is a virtual memory pointer to where Windows maintains your object, UINT msg, which is a numeric identifier such as WM_CREATE, WM_COMMAND, etc, and two additional params WPARAM and LPARAM. If you have a running program, and you so much as touch your mouse and move it over your program window for so much as a half a second, Windows will bombard your Window Procedure with dozens of calls, like a machine gun, and all of the calls will contain mouse move information, i.e., the coordinates of the mouse at that exact second. Everything that happens through the user's interaction with the computer Windows will inform your prog through calls into the Window Procedure. But I've discussed this all in great depth in my tutorial.

For all this to work though WinMain() needs an additional construct known as the 'Message Pump'. That is the while - wend block at the bottom with the GetMessage(), TranslateMessage(), and DispatchMessage() function calls. It is partly how data arrives in your Window Procedure through the working of this message pump. The other way is through Windows directly calling your Window Procedure.

Remember I said you never call your Window Procedure? Well, that's true, but there is an indirect way it may be done, and that is by use of the SendMessage() Api function. That function has a signature exactly the same as the Window Procedure, and you can send a message to your Window Procedure by calling the SendMessage function. Windows will then call your Window Procedure with the data you gave it in the SendMessage call. A possible reason for doing this would be to programmatically create a button click. So you would send a button click message.
On you website, what language are you using, PowerBasic?
Where do you talk about the Windows Procedure? On the link you gave me, I didn't see it, you were just going over code...Unless I missed it somewhere.
The first windows GUI program is actually in Reply #1 of that link, and is as follows ...

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
#include <windows.h>
#include <tchar.h>

LRESULT CALLBACK fnWndProc(HWND hwnd, unsigned int msg, WPARAM wParam, LPARAM lParam)
{
 switch(msg)
 {
  case WM_CREATE:      //This message is only received one time at program start up.  Think of it
    {                  //as a constructor call.
       MessageBox(hwnd,_T("Window Procedure Received WM_CREATE Message!"),_T("Message Report!"),MB_OK);
       return 0;
    }
  case WM_LBUTTONDOWN: //This message comes through when you click the form with your left mouse button.
    {
       MessageBox(hwnd,_T("Window Procedure Received WM_LBUTTONDOWN Message!"),_T("Message Report!"),MB_OK);
       return 0;
    }
  case WM_PAINT:       //This message comes through whenever any part of the window becoms 'invalid'.
    {                  //At program start up the whole window is invalid so must be drawn.
       TCHAR szBuffer[]=_T("Click Anywhere On Form (And Oh Yeah...Hello, World!)");
       //LPCTSTR szBuffer=_T("Click Anywhere On Form (And Oh Yeah...Hello, World!)"); // << can use this too
       PAINTSTRUCT ps;                                      // Necessary for BeginPaint(0 / EndPaint() calls
       HDC hDC;                                             // Handle (virtual memory pointer) to drawing characteristics
       hDC=BeginPaint(hwnd,&ps);                            // Required protocol for WM_PAINT handler
       int iBkMode=SetBkMode(hDC,TRANSPARENT);              // Save Background Mode characteristic of drawing context
       TextOut(hDC,40,20,szBuffer,(int)_tcslen(szBuffer));  // Draw Text
       SetBkMode(hDC,iBkMode);                              // Return Drawing Context To Original State
       EndPaint(hwnd,&ps);                                  // End Of WM_PAINT protocol
       return 0;
    }
  case WM_DESTROY:       //This message comes through when you click the [x] close button in the upper right
    {                    //corner of your window.
       MessageBox(hwnd,_T("Window Procedure Received WM_DESTROY Message!"),_T("Message Report!"),MB_OK);
       PostQuitMessage(0);
       return 0;
    }
 }

 return (DefWindowProc(hwnd, msg, wParam, lParam));
}


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int iShow)
{
 TCHAR szClassName[]=_T("Form1");
 WNDCLASSEX wc;
 MSG messages;
 HWND hWnd;

 wc.lpszClassName  =  szClassName;                     //Important Field!  Character string identifying window class
 wc.lpfnWndProc    =  fnWndProc;                       //Important Field!  Function Pointer.  Address of Window Procedure
 wc.cbSize         =  sizeof (WNDCLASSEX);             //Those top two fields I just listed are very important.  The
 wc.style          =  0;                               //others are of course necessary too, but fully understanding all
 wc.hIcon          =  LoadIcon(NULL,IDI_APPLICATION);  //the implications of the .szClassName and .lpfnWndProc fields will
 wc.hInstance      =  hInstance;                       //go a long way to helping you understand Win32 coding. The
 wc.hIconSm        =  0;                               //.hBrushBackground field will be the color of the Window's
 wc.hCursor        =  LoadCursor(NULL,IDC_ARROW);      //background.  The .cbWndExtra field is very useful as it allows
 wc.hbrBackground  =  (HBRUSH)COLOR_BTNSHADOW;         //you to associate object (Window) data to the instantiated Window's
 wc.cbWndExtra     =  0;                               //internal structure, i.e., accomodate member data.
 wc.cbClsExtra     =  0;
 wc.lpszMenuName   =  NULL;
 RegisterClassEx(&wc),
 hWnd=CreateWindowEx(0,szClassName,szClassName,WS_OVERLAPPEDWINDOW,350,250,450,300,HWND_DESKTOP,0,hInstance,0);
 ShowWindow(hWnd,iShow);
 while(GetMessage(&messages,NULL,0,0))                 //All important message pump.  This logic continually retrieves
 {                                                     //messages from the program's message queene and dispatches them
    TranslateMessage(&messages);                       //to the Window Procedure for processing.
    DispatchMessage(&messages);
 }

 return (int)messages.wParam;
}


If that isn't C/C++, I wish somebody would please tell me! I think it is though, at least far as I can tell.
That's from ProgEx37, which is the first program in my tutorial series specifically about C/C++ GUI programs. The whole tutorial series can be seen back one level here ...

http://www.jose.it-berater.org/smfforum/index.php?board=380.0

ProgEx38 - Window Procedure And Windows Messages is here ...

http://www.jose.it-berater.org/smfforum/index.php?topic=3390.0

I ought to update that for 64 bit. I see I have SetWindowLong() calls in it instead of SetWindowLongPtr().

If that isn't C/C++, I wish somebody would please tell me! I think it is though, at least far as I can tell.


I believe that is c++.

In computer programming, a parameter is a special kind of variable, used in a subroutine to refer to one of the pieces of data provided as input to the subroutine.[1] These pieces of data are called arguments.


So does this mean that
(HWND hwnd, unsigned int msg, WPARAM wParam, LPARAM lParam)
is the parameter and the information between the parenthesis is the argument?
Well that trailed off...

Again...

In computer programming, a parameter 
is a special kind of variable, used
 in a subroutine to refer to one of the pieces of 
data provided as input to the subroutine.[1] 
These pieces of data are called arguments.
From this example here:

double sales_tax(double price)
{
    return 0.05 * price;
}


The double would be the function; sales_tax is apparently a function, but 'tax' is a parameter, according to Wikipedia: http://en.wikipedia.org/wiki/Parameter_(computer_programming)
So wheres the argument? The 'double price?
1
2
3
4
double sales_tax(double price)
{
    return 0.05 * price;
} 


The function's name above is sales_tax

The function sales_tax has a return value, and the C/C++ variable type of the return value is a double.

The function sales_tax takes one (1) parameter named price, and the variable type of that parameter is a double.

There are some of us who think the distinction between parameter and arguement is overly academic.

So the Window Procedure has a return type of LRESULT and takes four parameters, i.e., a HWND, aunsigned int, a WPARAM, and a LPARAM.
From your questions psalm62, I'm beginning to suspect you may not be ready for this material. This material is advanced.

When Charles Petzold wrote his "Programming Windows" books, his target audience was professional C programmers who wanted to write graphical user interface programs for Microsoft Windows. In other words, his target audience had been programming commercially for years, and were accomplished at all aspects of C, which is a difficult low level language. For such people, Petzold said it would take about 6 months to learn Windows programming, even at a beginning level.

You may be better served by working on your programming in a console mode environment for several more months before even thinking about trying to do this material.
That's good information, I appreciate it. I think I have my first line covered -- I just needed an in depth understanding.

If you ever need help understanding web development, you can ask me.

:) Thank you very much
I don't know anything about web programming. From what I gather, that's the future. I've tried to get interested in it a few times, but I can't seem to work up any enthusiasm for it. Don't know why. Maybe its because where I work I do all the desktop and data recorder programming. I've specialized in that. From what I read though, the final word, the highest development and evolution of computer programming, has finally arrived. And what is that? Html and Java Script!
Pages: 123