Where can i learn GUI programing?

I am a home learner, currently i am using DEV C++, and i found many it is quite hard to find a source for me to learn about GUI, and i found most of them is for visual basic. Does the what are taught in Visual Basic are applicable in dev C++?
Like in this case, i want to my program catch the mouse's x and y coordinate when left button is pressed. So the code should:
1
2
3
4
5
6
7
8
9
10
11
12
int GET_X_LPARAM( //GET_X_PARAM should be declare before the windo procedure code?
  LPARAM lParam
);

//then i careate a case WM_LButtonDown
case WM_LBUTTONDBLCLK:
             {
             int xPos = GET_X_LPARAM(lParam);
             
             break;                
             }


and i get this error message 'cannot find -lobjc ', i know it is because that code is from MSDN library reference... and i am using DEV C++. So who do I change the code for the DEV CPP compiler?
I wasn't going to help you anymore selenium, because you aggravated me. Your 1st post was about that -lobj thing, and I solved your problem for you. I took the time to copy your code, create a project to test it, and at that point I saw where you had used main instead of WinMain() for your startup function. Also, you had forgotten the variable hPrevInstance in your WinMain procedure. I posted the corrected and compilable program for you and because it aggravated me so much that you hadn't even taken the care to copy the code correctly, but came here running for help without taking care to copy code correctly, I figurred I'd let you figure it out what you had done wrong.

When you replied you never thanked me for fixing your program, or acknowledged my contribution in any way; you simply threw out more garbage code in the hope someone would take the time to debug and fix it for you.

However, I do remember how I struggled when trying to learn this stuff. It is very difficult. I didn't have any internet when I tried to learn it. So here is a program that does exactly what you want, i.e., displays mouse coordinates when you click the mouse ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//Main.cpp
#define  UNICODE                    //Will cause 'W' versions of Api functions to be used.
#define  _UNICODE                   //Will cause wide character versions of C i/o to be used.
#include <windows.h>                //Master Windows include file
#include <tchar.h>                  //Macros for ansi/wide char support
#include <string>                   //C++ Standard String Class Support


struct ProgramData                  //This object will be used to persist mouse coordinate,
{                                   //client window dimensions, and left mouse click coordinates
 short int xMouse;                  //across invocations of the Window Procedure so that the
 short int yMouse;                  //data can be displayed on the window during WM_PAINT
 short int xSize;                   //messages.  An instance of this object will be allocated
 short int ySize;                   //dynamically in WM_CREATE, and the pointer to it stored
 short int xButton;                 //as instance data in the window's WNDCLASSEX::cbWndExtra
 short int yButton;                 //bytes.
};


continued ...

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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
LRESULT CALLBACK fnWndProc(HWND hwnd, unsigned int msg, WPARAM wParam, LPARAM lParam)
{
 ProgramData* pPD=NULL;

 switch(msg)
 {
    case WM_CREATE:                 //This message is only received once at program startup.
    {                               //Here we'll dynamically allocate memory on the heap to
         std::wstring* pStr;        //store inputs the program will receive in terms of key-
         pStr=new std::wstring;     //presses, mouse movements, button clicks, etc.  We'll
         SetWindowLong(hwnd,0,(long)pStr);//store pointers to this memory in 8 bytes we've
         pPD=(ProgramData*)GlobalAlloc(GPTR,sizeof(ProgramData));
         if(pPD)                    //allocated in theWNDCLASSEX struct down in WinMain()
         {
            SetWindowLong(hwnd,4,(long)pPD);
            return 0;
         }
         else
         {
            return -1;
         }
    }
    case WM_SIZE:          //Sent when the Window is first shown or resized.  We need
    {                      //to first retrieve the ProgramData* from the cbWndExtra
         pPD=(ProgramData*)GetWindowLong(hwnd,4); //bytes.  Then we can retrieve from
         pPD->xSize=LOWORD(lParam);               //lParam's lo and hi words the width
         pPD->ySize=HIWORD(lParam);               //and height of the window.  Then
         InvalidateRect(hwnd,NULL,TRUE);          //force a WM_PAINT to redraw the
         return 0;                                //newly acquired info.
    }
    case WM_CHAR:             //Sent when this program has the focus and the user hits
    {                         //a char on the keypad.  Same drill as above; retrieve
         std::wstring* pStr;  //String pointer though;  Then just add the wParam (which
         pStr=(std::wstring*)GetWindowLong(hwnd,0); //holds the key code pressed) to the
         *pStr+=+wParam;                            //String and force the repaint as
         InvalidateRect(hwnd,NULL,FALSE);           //above.
         return 0;
    }
    case WM_MOUSEMOVE:     //Sent when user moves mouse and mouse cursor is over this
    {                      //window.  1st retrieve ProgramData* from cbWndExtra bytes.
         pPD=(ProgramData*)GetWindowLong(hwnd,4);  //Then extract present mouse coord-
         pPD->xMouse=LOWORD(lParam);     //inates from lParam's Lo and Hi words.
         pPD->yMouse=HIWORD(lParam);     //Finally force repaint.
         InvalidateRect(hwnd,NULL,TRUE);
         return 0;
    }
    case WM_LBUTTONDOWN:   //Sent when user left button mouse clicks over window.  In
    {                      //terms of the rest, you should be getting the idea by now!
         pPD=(ProgramData*)GetWindowLong(hwnd,4);
         pPD->xButton=LOWORD(lParam);
         pPD->yButton=HIWORD(lParam);
         InvalidateRect(hwnd,NULL,FALSE);
         return 0;
    }
    case WM_PAINT:         //All drawing to a window should be done during a WM_PAINT message.
    {                      //That is why in all of the above message handling code except that
         PAINTSTRUCT ps;   //for WM_CREATE there is an InvalidateRect() Api call.  That call
         std::wstring s1;  //will cause Windows to invalidate the client area of the window,
         std::wstring s2;  //and when this occurs windows will post to the window's message
         std::wstring* pStr;       //queue a WM_PAINT message.  In this code just left we are
         TCHAR szBuffer[16];       //allocating a few standard string objects, and a TCHAR
         HDC hDC;                  //buffer.  These will support the text we wish to display
         hDC=BeginPaint(hwnd,&ps); //using TextOut().  What we first do though is call
         pPD=(ProgramData*)GetWindowLong(hwnd,4);      //BeginPaint() to get a handle to a
         s1=_T("xMouse=");                             //device context (which is necessary
         _stprintf(szBuffer,_T("%d"),pPD->xMouse);     //for GDI (Graphics Device Interface)
         s2=szBuffer;                                  //function calls, and then call
         s1+=s2+_T("     yMouse=");                    //GetWindowLong() to retrieve our
         _stprintf(szBuffer,_T("%d"),pPD->yMouse);     //ProgramData pointer from the Window
         s2=szBuffer;                                  //Class struct.  Having done that we can
         s1+=s2;                                       //chug through some string minipulation
         TextOut(hDC,0,0,s1.c_str(),s1.length());      //code to compose the messages we want
         if(pPD->xButton||pPD->yButton)                //to display in our window, which
         {                                             //messages contain the various numeric
            s1=_T("xButton=");                         //information we want to convey.  Note
            _stprintf(szBuffer,_T("%d"),pPD->xButton); //that _stprintf() is used to convert
            s2=szBuffer;                               //the integral data to a string format
            s1+=s2+_T("    yButton=");                 //so it can be output in a std::string.
            _stprintf(szBuffer,_T("%d"),pPD->yButton); //If you know a better way to do it go
            s2=szBuffer;                               //for it.  I'm not really expert on the
            s1+=s2;                                    //std::string class, as I mostly use my
            TextOut                                    //own.  Finally, after outputting all
            (                                          //the data we want we need to call
             hDC,                                      //EndPaint() to release the device
             pPD->xButton+12,                          //context.  This is important because
             pPD->yButton,                             //if you don't release memory objects
             s1.c_str(),                               //and resources back to the operating
             s1.length()                               //system you'll cause a memory leak, and
            );                                         //your program will start to behave
            pPD->xButton=0, pPD->yButton=0;            //rather badly.  Essentially, .NET
         }                                             //is Microsoft's answer to the problem
         s1=_T("Width=");                              //that the average coder can't be trusted
         _stprintf(szBuffer,_T("%d"),pPD->xSize);      //to do things like this correctly, so
         s2=szBuffer;                                  //the framework takes care of it for
         s1+=s2+_T("    Height=");                     //him/her.  So you've got to ask yourself,
         _stprintf(szBuffer,_T("%d"),pPD->ySize);      //"Are you better than the average coder?"
         s2=szBuffer;                                  //
         s1+=s2;                                       //In WM_DESTROY below we'll release the
         TextOut(hDC,0,20,s1.c_str(),s1.length());     //std::string pointer we acquired with
         pStr=(std::wstring*)GetWindowLong(hwnd,0);    //new by calling delete on it, and we'll
         TextOut(hDC,0,40,pStr->c_str(),pStr->length());  //use GlobalFree() on the ProgramData
         EndPaint(hwnd,&ps);                              //pointer we acquired with GlobalAlloc().
         return 0;
    }
    case WM_DESTROY:
    {
         std::wstring* pStr;
         pStr=(std::wstring*)GetWindowLong(hwnd,0);
         delete pStr;
         pPD=(ProgramData*)GetWindowLong(hwnd,4);
         if(pPD)
            GlobalFree(pPD);   //send the WM_DESTROY.  Anyway, what we need to do here is
         PostQuitMessage(0);//release our heap allocations and post a Quit message.
         return 0;
    }
 }

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


continued ...
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
int WINAPI WinMain(HINSTANCE hIns, HINSTANCE hPrevIns, LPSTR lpszArgument, int iShow)
{
 TCHAR szClassName[]=_T("Form2");
 TCHAR szCaption[80];
 WNDCLASSEX wc;
 MSG messages;
 HWND hWnd;

 wc.lpszClassName=szClassName,                          wc.lpfnWndProc=fnWndProc;
 wc.cbSize=sizeof (WNDCLASSEX),                         wc.style=CS_DBLCLKS;
 wc.hIcon=LoadIcon(NULL,IDI_APPLICATION),               wc.hInstance=hIns;
 wc.hIconSm=LoadIcon(NULL, IDI_APPLICATION),            wc.hCursor=LoadCursor(NULL,IDC_ARROW);
 wc.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH),  wc.cbWndExtra=8;
 wc.lpszMenuName=NULL,                                  wc.cbClsExtra=0;
 RegisterClassEx(&wc);
 _tcscpy(szCaption,_T("Try Typing Text, Moving Mouse, Clicking Left Mouse Button, Or Sizing Window!"));
 hWnd=CreateWindowEx(0,szClassName,szCaption,WS_OVERLAPPEDWINDOW,100,100,600,400,HWND_DESKTOP,0,hIns,0);
 ShowWindow(hWnd,iShow);
 while(GetMessage(&messages,NULL,0,0))
 {
    TranslateMessage(&messages);
    DispatchMessage(&messages);
 }

 return messages.wParam;
}
Very sorry about the previous post, I just realize that my knowledge about this GUI is too shallow, I don't understand most of the part of the code. And I decided that I will start over, to read more about GUI theory in msdn. For now, i will save down all the code that you posted, and will study it back when i learned enough from msdn.

And once again , sorry and thanks for your hard work.
Apology accepted.

You might just be able to figure out the above program and understand it if you read the whole tutorial I took it from, which has detailed explanations of everything covered in the cryptic comments next to the code above. That tutorial describing the above program is here ...

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

Somewhat more basic is here ...

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

For your information C++ is the most difficult way to start with GUI programming in Windows. That is because there is nothing in the C or C++ languages specific to Graphical User Interfaces. All GUIs are 'Platform Specific'. In the case of Microsoft Windows, the lowest level programatic interface to the GUI is through the C based Windows API. While there is a lot of information out there on using the Windows API, there are very few books specifically on the topic for learners like yourself wishing to get started. The most popular and widely used book has been Charles Petzold's 'Programming Windows'. Either the 4th or 5th edition is good. This book explains the theory and the big picture.

In the above program, I made it more complex than it has to be because I eliminated all global variables and used dynamically allocated memory instead where I stored memory pointers as part of the Window Class structure. That is what the 'ProgramData' struct is about. In C, and in the Windows Api, becomming familiar and good with pointers is very important.
Ok I know where to start already, thanks.
Topic archived. No new replies allowed.