+ Reply to Thread
Results 1 to 3 of 3

Thread: How to create a Window and Button control in Window 32 API?

  1. #1
    Senior Member
    Join Date
    Feb 2012
    Posts
    109

    How to create a Window and Button control in Window 32 API?

    I would like to know how to create a Window in WIN32 API and create a button child control on it and how to handle its click event?

    Thanks!

  2. #2
    This article describes:

    a. How to create a Window using Win32 API?
    b. How to create a button child control in the Main window.
    c. Handle click event of the button control.

    1. RegisterWindowClass

    First task for a WIN32 application is to register a Window class.
    Window class is a entity which represent certain properties of the window.
    For example, Icon of the Window, Cursor, and main thing is Window procedure for the Window.

    Window procedure
    Window procedure is the main part of the Win32 programming.
    Each Window can have its own Window procedure. Window procedure handles the event corresponding to it its child control.

    Whenever any event occur particular to window then system (Windows OS) call to Window procedure of the corresponding window.

    2. InitInstance

    Once a Window class is registered, application then creates Main Window.
    Main Window is the window which will be part of the application for its entire life-time.
    Main Window has many parts. System Menu, Frame, Title-bar, Minimize, Maximize, Close buttons etc...
    You can override these window parts as per your requirement.

    3. Message Loop

    Windows is an event driven operating system.

    Each Window has its Window procedure and is getting called by the system when there is any event is occurred.

    To get the message from the queue, Window application has to listen to the message queue and process it whenever there is any message for it.

    4. Create Button control

    Whenever window creates, window procedure will get WM_CREATE message.
    Here, main Window can create its child controls. We have created just a button control.
    Button is a control which can be clicked. Upon click, application can perform certain task.

    5. User click on the button

    When user clicks on the button, Main Window procedure will get the WM_COMMAND message.

    Where Window procedure further identifies the content of the message can perform activities based on the message content.

    In this example, we display a message when user presses the button.

    Code:
    #include <windows.h>
    #include <stdlib.h>
    #include <malloc.h>
    #include <memory.h>
    #include <tchar.h>
    #include <stdio.h>
    
    #define			BUTTON_IDENTIFIER	1
    
    HINSTANCE		ghInstance = NULL ;
    ATOM			RegisterWindowClass(HINSTANCE hInstance, char *pszWindowClassName) ;
    BOOL			InitInstance(HINSTANCE, int, char *pszWindowClassName) ;
    LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM) ;
    
    int APIENTRY _tWinMain(HINSTANCE hInstance,
                         HINSTANCE hPrevInstance,
                         LPTSTR    lpCmdLine,
                         int       nCmdShow)
    {
    	//Step 1: Register a Window Class..
    	char *pszWindowClassName = "Button Event Class" ;
    	if(RegisterWindowClass(hInstance, pszWindowClassName) == 0)
    	{
    		char szMessage[1024] ;
    		sprintf(szMessage, "Last Error = %d", GetLastError()) ;
    		OutputDebugString(szMessage) ;
    		return -1 ;
    	}
    
    	ghInstance = hInstance ;
    
    	//Step 2: Create a Main Window..
    	if (!InitInstance(hInstance, nCmdShow, pszWindowClassName))
    	{
    		return -1 ;
    	}
    
    	//Step 3: Loop through the message
    	MSG msg ;
    	while (GetMessage(&msg, NULL, 0, 0))
    	{
    		TranslateMessage(&msg);
    		DispatchMessage(&msg);
    	}
    }
    
    ATOM RegisterWindowClass(HINSTANCE hInstance, char *pszWindowClassName)
    {
    	WNDCLASSEX objWndClassEx ;
    
    	memset(&objWndClassEx, 0, sizeof(objWndClassEx)) ;
    
    	objWndClassEx.cbSize		= sizeof(WNDCLASSEX) ;
    	objWndClassEx.style			= CS_HREDRAW | CS_VREDRAW ;
    	objWndClassEx.lpfnWndProc	= WndProc ;
    	objWndClassEx.hInstance		= hInstance ;
    	objWndClassEx.hIcon			= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION)) ;
    	objWndClassEx.hCursor		= LoadCursor(NULL, IDC_ARROW) ;
    	objWndClassEx.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1) ;
    	objWndClassEx.lpszClassName	= pszWindowClassName ;
    
    	return RegisterClassEx(&objWndClassEx);
    }
    
    BOOL InitInstance(HINSTANCE hInstance, int nCmdShow, char *pszWindowClassName)
    {
    	int nWidth	= 200 ;
    	int nHeight	= 200 ;
    
    	int nScreenX = GetSystemMetrics(SM_CXSCREEN) ;
    	int nScreenY = GetSystemMetrics(SM_CYSCREEN) ;
    
    	int x = (nScreenX / 2) - (nWidth / 2) ;
    	int y = (nScreenY / 2) - (nHeight / 2) ;
    
    	//Create main Window
    	HWND hWnd = CreateWindowEx(NULL, pszWindowClassName, "Button Event Example", WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX, x, y, nWidth, nHeight, NULL, NULL, hInstance, NULL) ;
    
    	if (NULL == hWnd)
    	{
    		char szMessage[1024] ;
    		sprintf(szMessage, "Last Error = %d", GetLastError()) ;
    		OutputDebugString(szMessage) ;
    		return FALSE ;
    	}
    
    	//Display window that we just created.
    	ShowWindow(hWnd, nCmdShow) ;
    	UpdateWindow(hWnd) ;
    
    	return TRUE ;
    }
    
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	switch (message)
    	{
    	case WM_CREATE:
    		{
    			//Step 4: Create Button control
    			int nWidth	= 70 ;
    			int nHeight	= 30 ;
    			RECT rect ;
    			GetClientRect(hWnd, &rect) ;
    			HWND hButtonWnd = CreateWindowEx(NULL, "BUTTON", "Click Me!", WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,
    								(rect.right - rect.left - nWidth) / 2, 
    								(rect.bottom - rect.top - nHeight) / 2,
    								nWidth, nHeight, hWnd, (HMENU) BUTTON_IDENTIFIER, ghInstance, NULL) ;
    		}
    		break ;
    
    	case WM_COMMAND:
    		{
    			switch(LOWORD(wParam))
    			{
    			case BUTTON_IDENTIFIER:
    				{
    					//Step 5: User click on the button
    					if (HIWORD(wParam) == BN_CLICKED)
    					{
    						UINT nButton	= (UINT) LOWORD(wParam) ;
    						HWND hButtonWnd = (HWND) lParam ;
    
    						char szMessage[1024] ;
    						sprintf(szMessage, "Hello World from Click Me. Button ID is = %d", nButton) ;
    						MessageBox(hWnd, szMessage, "Click Me", MB_OK) ;
    					}
    				}
    				break ;
    			}
    		}
    		break ;
    
    	case WM_CLOSE:
    		DestroyWindow(hWnd) ;
    		break ;
    
    	case WM_DESTROY:
    		PostQuitMessage(0);
    		break;
    
    	default:
    		return DefWindowProc(hWnd, message, wParam, lParam) ;
    	}
    
    	return 0 ;
    }
    Last edited by Harry; 03-17-2012 at 03:25 AM.

  3. #3
    Below is another technique to handle button events.

    6. Another way to handle Button events

    There a another way to handle the event handler for the button control. This can be done by using WinProc for button control itself.

    Whenever we create a button control, we can set the WinProc for the button. SetWindowLong and GWL_WNDPROC can be used for this.

    gpOriginalWindowProc = (WNDPROC) SetWindowLong(ghButtonWnd, GWL_WNDPROC, (LONG) ButtonWndProc) ;

    Here, ButtonWndProc if the WinProc for the Button. When user presses mouse button on button, button control will get mouse event directly.

    This can be left mouse up/down etc..

    Following is the example where WinProc for a button catches Left Mouse Button event:

    Code:
    #include <windows.h>
    #include <stdlib.h>
    #include <malloc.h>
    #include <memory.h>
    #include <tchar.h>
    #include <stdio.h>
    
    #define				BUTTON_IDENTIFIER	1
    
    HINSTANCE			ghInstance = NULL ;
    ATOM				RegisterWindowClass(HINSTANCE hInstance, char *pszWindowClassName) ;
    BOOL				InitInstance(HINSTANCE, int, char *pszWindowClassName) ;
    LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM) ;
    
    WNDPROC gpOriginalWindowProc	= NULL ;
    HWND	ghButtonWnd				= NULL ;
    LRESULT CALLBACK	ButtonWndProc(HWND, UINT, WPARAM, LPARAM) ;
    
    int APIENTRY _tWinMain(HINSTANCE hInstance,
                         HINSTANCE hPrevInstance,
                         LPTSTR    lpCmdLine,
                         int       nCmdShow)
    {
    	//Step 1: Register a Window Class..
    	char *pszWindowClassName = "Button Event Class" ;
    	if(RegisterWindowClass(hInstance, pszWindowClassName) == 0)
    	{
    		char szMessage[1024] ;
    		sprintf(szMessage, "Last Error = %d", GetLastError()) ;
    		OutputDebugString(szMessage) ;
    		return -1 ;
    	}
    
    	ghInstance = hInstance ;
    
    	//Step 2: Create a Main Window..
    	if (!InitInstance(hInstance, nCmdShow, pszWindowClassName))
    	{
    		return -1 ;
    	}
    
    	//Step 3: Loop through the message
    	MSG msg ;
    	while (GetMessage(&msg, NULL, 0, 0))
    	{
    		TranslateMessage(&msg);
    		DispatchMessage(&msg);
    	}
    }
    
    ATOM RegisterWindowClass(HINSTANCE hInstance, char *pszWindowClassName)
    {
    	WNDCLASSEX objWndClassEx ;
    
    	memset(&objWndClassEx, 0, sizeof(objWndClassEx)) ;
    
    	objWndClassEx.cbSize		= sizeof(WNDCLASSEX) ;
    	objWndClassEx.style			= CS_HREDRAW | CS_VREDRAW ;
    	objWndClassEx.lpfnWndProc	= WndProc ;
    	objWndClassEx.hInstance		= hInstance ;
    	objWndClassEx.hIcon			= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION)) ;
    	objWndClassEx.hCursor		= LoadCursor(NULL, IDC_ARROW) ;
    	objWndClassEx.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1) ;
    	objWndClassEx.lpszClassName	= pszWindowClassName ;
    
    	return RegisterClassEx(&objWndClassEx);
    }
    
    BOOL InitInstance(HINSTANCE hInstance, int nCmdShow, char *pszWindowClassName)
    {
    	int nWidth	= 200 ;
    	int nHeight	= 200 ;
    
    	int nScreenX = GetSystemMetrics(SM_CXSCREEN) ;
    	int nScreenY = GetSystemMetrics(SM_CYSCREEN) ;
    
    	int x = (nScreenX / 2) - (nWidth / 2) ;
    	int y = (nScreenY / 2) - (nHeight / 2) ;
    
    	//Create main Window
    	HWND hWnd = CreateWindowEx(NULL, pszWindowClassName, "Button Event Example", WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX,
    								x, y, nWidth, nHeight, NULL, NULL, hInstance, NULL) ;
    
    	if (NULL == hWnd)
    	{
    		char szMessage[1024] ;
    		sprintf(szMessage, "Last Error = %d", GetLastError()) ;
    		OutputDebugString(szMessage) ;
    		return FALSE ;
    	}
    
    	//Display window that we just created.
    	ShowWindow(hWnd, nCmdShow) ;
    	UpdateWindow(hWnd) ;
    
    	return TRUE ;
    }
    
    LRESULT CALLBACK ButtonWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	switch (message)
    	{
    	case WM_LBUTTONUP:
    		{
    			char szMessage[1024] ;
    			sprintf(szMessage, "Hello World from Click Me.") ;
    			MessageBox(hWnd, szMessage, "Click Me", MB_OK) ;
    			return TRUE ;
    		}
    		break ;
    	}
    	return CallWindowProc(gpOriginalWindowProc, hWnd, message, wParam, lParam) ; 
    }
    
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	switch (message)
    	{
    	case WM_CREATE:
    		{
    			//Step 4: Create Button control
    			int nWidth	= 70 ;
    			int nHeight	= 30 ;
    			RECT rect ;
    			GetClientRect(hWnd, &rect) ;
    			ghButtonWnd = CreateWindowEx(NULL, "BUTTON", "Click Me!", WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,
    								(rect.right - rect.left - nWidth) / 2, 
    								(rect.bottom - rect.top - nHeight) / 2,
    								nWidth, nHeight, hWnd, (HMENU) BUTTON_IDENTIFIER, ghInstance, NULL) ;
    
    			gpOriginalWindowProc = (WNDPROC) SetWindowLong(ghButtonWnd, GWL_WNDPROC, (LONG) ButtonWndProc) ;
    		}
    		break ;
    
    	case WM_CLOSE:
    		DestroyWindow(hWnd) ;
    		break ;
    
    	case WM_DESTROY:
    		SetWindowLong(ghButtonWnd, GWL_WNDPROC, (LONG) gpOriginalWindowProc) ;
    		PostQuitMessage(0);
    		break;
    
    	default:
    		return DefWindowProc(hWnd, message, wParam, lParam) ;
    	}
    
    	return 0 ;
    }

+ Reply to Thread

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts