Thread: Api child window

  1. #1
    Registered User BraneMxm's Avatar
    Join Date
    Apr 2007
    Location
    Croatia
    Posts
    20

    Api child window

    I have a assignement that i have to do, i am not bad in c. But i never done windows programming before.

    Here is the task:

    Win32 API aplication with 3 windows. all should be created with the same class. Number one should own nuber two, and number two should own number 3. And i should describe how the ownership of the windows affects their appereance.

    I created something and thw windows open one in another. But when i close one(doesnt mather which) they all close. Like i said i am no good in Winrogramming so i dont even know if it should be this way.

    Here is my code:
    Code:
    #include "stdafx.h"
    #include "vjezba4dio.h"
    
    #define MAX_LOADSTRING 100
    
    // Global Variables:
    HINSTANCE hInst;								// current instance
    TCHAR szTitle[MAX_LOADSTRING];					// The title bar text
    TCHAR szWindowClass[MAX_LOADSTRING];			// the main window class name
    
    // Forward declarations of functions included in this code module:
    ATOM				MyRegisterClass(HINSTANCE hInstance);
    BOOL				InitInstance(HINSTANCE, int);
    LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM);
    INT_PTR CALLBACK	About(HWND, UINT, WPARAM, LPARAM);
    
    int APIENTRY _tWinMain(HINSTANCE hInstance,
                         HINSTANCE hPrevInstance,
                         LPTSTR    lpCmdLine,
                         int       nCmdShow)
    {
    	UNREFERENCED_PARAMETER(hPrevInstance);
    	UNREFERENCED_PARAMETER(lpCmdLine);
    
     	// TODO: Place code here.
    	MSG msg;
    	HACCEL hAccelTable;
    
    	// Initialize global strings
    	LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
    	LoadString(hInstance, IDC_VJEZBA4DIO, szWindowClass, MAX_LOADSTRING);
    	MyRegisterClass(hInstance);
    
    	// Perform application initialization:
    	if (!InitInstance (hInstance, nCmdShow))
    	{
    		return FALSE;
    	}
    
    	hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_VJEZBA4DIO));
    
    	// Main message loop:
    	while (GetMessage(&msg, NULL, 0, 0))
    	{
    		if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
    		{
    			TranslateMessage(&msg);
    			DispatchMessage(&msg);
    		}
    	}
    
    	return (int) msg.wParam;
    }
    
    
    
    //
    //  FUNCTION: MyRegisterClass()
    //
    //  PURPOSE: Registers the window class.
    //
    //  COMMENTS:
    //
    //    This function and its usage are only necessary if you want this code
    //    to be compatible with Win32 systems prior to the 'RegisterClassEx'
    //    function that was added to Windows 95. It is important to call this function
    //    so that the application will get 'well formed' small icons associated
    //    with it.
    //
    ATOM MyRegisterClass(HINSTANCE hInstance)
    {
    	WNDCLASSEX wcex;
    
    	wcex.cbSize = sizeof(WNDCLASSEX);
    
    	wcex.style			= CS_HREDRAW | CS_VREDRAW;
    	wcex.lpfnWndProc	= WndProc;
    	wcex.cbClsExtra		= 0;
    	wcex.cbWndExtra		= 0;
    	wcex.hInstance		= hInstance;
    	wcex.hIcon			= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_VJEZBA4DIO));
    	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
    	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
    	wcex.lpszMenuName	= MAKEINTRESOURCE(IDC_VJEZBA4DIO);
    	wcex.lpszClassName	= szWindowClass;
    	wcex.hIconSm		= LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
    
    	return RegisterClassEx(&wcex);
    }
    
    //
    //   FUNCTION: InitInstance(HINSTANCE, int)
    //
    //   PURPOSE: Saves instance handle and creates main window
    //
    //   COMMENTS:
    //
    //        In this function, we save the instance handle in a global variable and
    //        create and display the main program window.
    //
    BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
    {
       HWND hWnd;
       HWND hWnd1;
       HWND hWnd2;
    
       hInst = hInstance; // Store instance handle in our global variable
    
       hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
          CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
    
       if (!hWnd)
       {
          return FALSE;
       }
    
       ShowWindow(hWnd, nCmdShow);
       UpdateWindow(hWnd);
    
    hWnd1 = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW | WS_CHILD | WS_VISIBLE,
          CW_USEDEFAULT, 0, 500,300,hWnd, NULL, hInstance, NULL);
    
    
       if (!hWnd1)
       {
          return FALSE;
       }
    
      ShowWindow(hWnd1, nCmdShow);
       UpdateWindow(hWnd1);
    
        hWnd2 = CreateWindow(szWindowClass, szTitle,WS_OVERLAPPEDWINDOW |  WS_CHILD | WS_VISIBLE,
          CW_USEDEFAULT, 0, 200, 100,hWnd1, NULL, hInstance, NULL);
    
       if (!hWnd2)
       {
          return FALSE;
       }
    
      ShowWindow(hWnd2, nCmdShow);
      UpdateWindow(hWnd2);
    
       return TRUE;
    }
    
    //
    //  FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
    //
    //  PURPOSE:  Processes messages for the main window.
    //
    //  WM_COMMAND	- process the application menu
    //  WM_PAINT	- Paint the main window
    //  WM_DESTROY	- post a quit message and return
    //
    //
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	int wmId, wmEvent;
    	PAINTSTRUCT ps;
    	HDC hdc;
    
    	switch (message)
    	{
    		
    	case WM_COMMAND:
    		wmId    = LOWORD(wParam);
    		wmEvent = HIWORD(wParam);
    		// Parse the menu selections:
    		switch (wmId)
    		{
    		
    		case IDM_ABOUT:
    			DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
    			break;
    		case IDM_EXIT:
    			DestroyWindow(hWnd);
    			break;
    		default:
    			return DefWindowProc(hWnd, message, wParam, lParam);
    		}
    		break;
    	case WM_PAINT:
    		hdc = BeginPaint(hWnd, &ps);
    		// TODO: Add any drawing code here...
    		EndPaint(hWnd, &ps);
    		break;
    	case WM_DESTROY:
    		PostQuitMessage(0);
    		break;
    	default:
    		return DefWindowProc(hWnd, message, wParam, lParam);
    	}
    	return 0;
    }
    
    // Message handler for about box.
    INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	UNREFERENCED_PARAMETER(lParam);
    	switch (message)
    	{
    	case WM_INITDIALOG:
    		return (INT_PTR)TRUE;
    
    	case WM_COMMAND:
    		if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
    		{
    			EndDialog(hDlg, LOWORD(wParam));
    			return (INT_PTR)TRUE;
    		}
    		break;
    	}
    	return (INT_PTR)FALSE;
    }

  2. #2
    Registered User Queatrix's Avatar
    Join Date
    Apr 2005
    Posts
    1,342
    Code:
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    should be
    Code:
    LRESULT CALLBACK WndProc(HWND hWndLocal, UINT message, WPARAM wParam, LPARAM lParam)
    And
    Code:
    	case WM_DESTROY:
    		PostQuitMessage(0);
    		break;
    should be
    Code:
    case WM_DESTROY:
    {
       if(hWndLocal == hWnd)
       {
          DestroyWindow(hWnd2);
          DestroyWindow(hWnd1);
          DestroyWindow(hWnd);
          PostQuitMessage(0);
       }
       else if(hWndLocal == hWnd1)
       {
          DestroyWindow(hWnd2);
          DestroyWindow(hWnd1);
       }
       else if(hWndLocal == hWnd2)
       {
          DestroyWindow(hWnd2);
       }
       else
       {
          MessageBox(NULL, "hWnd parameter invalid!", "Error!", MB_OK | MB_ERROR);
          PostQuitMessage(0);
       }
    }
    break;
    And you need to make these global:
    Code:
    HWND hWnd;
    HWND hWnd1;
    HWND hWnd2;

  3. #3
    Registered User BraneMxm's Avatar
    Join Date
    Apr 2007
    Location
    Croatia
    Posts
    20

    Nothing happens

    I had two errors in this line so icomented it out
    // MessageBox(NULL, "hWnd parameter invalid!", "Error!", MB_OK | MB_ERROR);
    The errors were:
    C2065 'MB_ERROR' undeclared identifier
    MessageboxWCannot convert par 2 from const char[] to lpcWstr
    I am working with visuallStudio2005 can this be the reason.



    Now there are no errors but nothing happens no window shows up!
    Here the changed code again:

    Thanks
    Code:
    // vjezba4.cpp : Defines the entry point for the application.
    //
    
    #include "stdafx.h"
    #include "vjezba4.h"
    
    #define MAX_LOADSTRING 100
    
    // Global Variables:
    HINSTANCE hInst;								// current instance
    TCHAR szTitle[MAX_LOADSTRING];					// The title bar text
    TCHAR szWindowClass[MAX_LOADSTRING];			// the main window class name
    HWND hWnd;
    HWND hWnd1;
    HWND hWnd2;
    // Forward declarations of functions included in this code module:
    ATOM				MyRegisterClass(HINSTANCE hInstance);
    BOOL				InitInstance(HINSTANCE, int);
    LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM);
    INT_PTR CALLBACK	About(HWND, UINT, WPARAM, LPARAM);
    
    int APIENTRY _tWinMain(HINSTANCE hInstance,
                         HINSTANCE hPrevInstance,
                         LPTSTR    lpCmdLine,
                         int       nCmdShow)
    {
    	UNREFERENCED_PARAMETER(hPrevInstance);
    	UNREFERENCED_PARAMETER(lpCmdLine);
    
     	// TODO: Place code here.
    	MSG msg;
    	HACCEL hAccelTable;
    
    	// Initialize global strings
    	LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
    	LoadString(hInstance, IDC_VJEZBA4, szWindowClass, MAX_LOADSTRING);
    	MyRegisterClass(hInstance);
    
    	// Perform application initialization:
    	if (!InitInstance (hInstance, nCmdShow))
    	{
    		return FALSE;
    	}
    
    	hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_VJEZBA4));
    
    	// Main message loop:
    	while (GetMessage(&msg, NULL, 0, 0))
    	{
    		if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
    		{
    			TranslateMessage(&msg);
    			DispatchMessage(&msg);
    		}
    	}
    
    	return (int) msg.wParam;
    }
    
    
    
    //
    //  FUNCTION: MyRegisterClass()
    //
    //  PURPOSE: Registers the window class.
    //
    //  COMMENTS:
    //
    //    This function and its usage are only necessary if you want this code
    //    to be compatible with Win32 systems prior to the 'RegisterClassEx'
    //    function that was added to Windows 95. It is important to call this function
    //    so that the application will get 'well formed' small icons associated
    //    with it.
    //
    ATOM MyRegisterClass(HINSTANCE hInstance)
    {
    	WNDCLASSEX wcex;
    
    	wcex.cbSize = sizeof(WNDCLASSEX);
    
    	wcex.style			= CS_HREDRAW | CS_VREDRAW;
    	wcex.lpfnWndProc	= WndProc;
    	wcex.cbClsExtra		= 0;
    	wcex.cbWndExtra		= 0;
    	wcex.hInstance		= hInstance;
    	wcex.hIcon			= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_VJEZBA4));
    	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
    	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
    	wcex.lpszMenuName	= MAKEINTRESOURCE(IDC_VJEZBA4);
    	wcex.lpszClassName	= szWindowClass;
    	wcex.hIconSm		= LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
    
    	return RegisterClassEx(&wcex);
    }
    
    //
    //   FUNCTION: InitInstance(HINSTANCE, int)
    //
    //   PURPOSE: Saves instance handle and creates main window
    //
    //   COMMENTS:
    //
    //        In this function, we save the instance handle in a global variable and
    //        create and display the main program window.
    //
    BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
    {
      hInst = hInstance; // Store instance handle in our global variable
    
       hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
          CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
    
       if (!hWnd)
       {
          return FALSE;
       }
    
       ShowWindow(hWnd, nCmdShow);
       UpdateWindow(hWnd);
    
    hWnd1 = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW | WS_CHILD | WS_VISIBLE,
          CW_USEDEFAULT, 0, 500,300,hWnd, NULL, hInstance, NULL);
    
    
       if (!hWnd1)
       {
          return FALSE;
       }
    
      ShowWindow(hWnd1, nCmdShow);
       UpdateWindow(hWnd1);
    
        hWnd2 = CreateWindow(szWindowClass, szTitle,WS_OVERLAPPEDWINDOW |  WS_CHILD | WS_VISIBLE,
          CW_USEDEFAULT, 0, 200, 100,hWnd1, NULL, hInstance, NULL);
    
       if (!hWnd2)
       {
          return FALSE;
       }
    
      ShowWindow(hWnd2, nCmdShow);
      UpdateWindow(hWnd2);
    
       return TRUE;
    }
    
    //
    //  FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
    //
    //  PURPOSE:  Processes messages for the main window.
    //
    //  WM_COMMAND	- process the application menu
    //  WM_PAINT	- Paint the main window
    //  WM_DESTROY	- post a quit message and return
    //
    //
    LRESULT CALLBACK WndProc(HWND hWndLocal, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	int wmId, wmEvent;
    	PAINTSTRUCT ps;
    	HDC hdc;
    
    	switch (message)
    	{
    	case WM_COMMAND:
    		wmId    = LOWORD(wParam);
    		wmEvent = HIWORD(wParam);
    		// Parse the menu selections:
    		switch (wmId)
    		{
    		case IDM_ABOUT:
    			DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
    			break;
    		case IDM_EXIT:
    			DestroyWindow(hWnd);
    			break;
    		default:
    			return DefWindowProc(hWnd, message, wParam, lParam);
    		}
    		break;
    	case WM_PAINT:
    		hdc = BeginPaint(hWnd, &ps);
    		// TODO: Add any drawing code here...
    		EndPaint(hWnd, &ps);
    		break;
    	case WM_DESTROY:
    {
       if(hWndLocal == hWnd)
       {
          DestroyWindow(hWnd2);
          DestroyWindow(hWnd1);
          DestroyWindow(hWnd);
          PostQuitMessage(0);
       }
       else if(hWndLocal == hWnd1)
       {
          DestroyWindow(hWnd2);
          DestroyWindow(hWnd1);
       }
       else if(hWndLocal == hWnd2)
       {
          DestroyWindow(hWnd2);
       }
       else
       {
         // MessageBox(NULL, "hWnd parameter invalid!", "Error!", MB_OK | MB_ERROR);
          PostQuitMessage(0);
       }
    }
    break;
    		break;
    	default:
    		return DefWindowProc(hWnd, message, wParam, lParam);
    	}
    	return 0;
    }
    
    // Message handler for about box.
    INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	UNREFERENCED_PARAMETER(lParam);
    	switch (message)
    	{
    	case WM_INITDIALOG:
    		return (INT_PTR)TRUE;
    
    	case WM_COMMAND:
    		if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
    		{
    			EndDialog(hDlg, LOWORD(wParam));
    			return (INT_PTR)TRUE;
    		}
    		break;
    	}
    	return (INT_PTR)FALSE;
    }

  4. #4
    int x = *((int *) NULL); Cactus_Hugger's Avatar
    Join Date
    Jul 2003
    Location
    Banks of the River Styx
    Posts
    902
    I had two errors in this line so icomented it out
    // MessageBox(NULL, "hWnd parameter invalid!", "Error!", MB_OK | MB_ERROR);
    The errors were:
    C2065 'MB_ERROR' undeclared identifier
    MessageboxWCannot convert par 2 from const char[] to lpcWstr
    I am working with visuallStudio2005 can this be the reason.
    You're compiling a Unicode app by the looks of it. Surround your string literals with TEXT(). (ie, TEXT("hWnd parameter invalid!") and TEXT("Error!") ). Also, MB_ERROR should be MB_ICONERROR.

    However, I don't understand his approach to WM_DESTROY. After your main window is done with WM_DESTROY, its children will be destroyed automagically, so there's no need to manually call DestroyWindow()... (Furthermore, calling DestroyWindow() on yourself in your WM_DESTROY message is pointless - WM_DESTROY means you're in the process of being destroyed...)

    Let's go back to your original. There, when any window is closed, the window procedure calls PostQuitMessage(), which will end your app. (Closing all the other windows) Create a variable called "HWND hParent", global, set to the handle of your outermost/first created window. Then, in your window procedure, do:
    Code:
    	case WM_DESTROY:
    		if(hWnd == hParent) PostQuitMessage(0);
    		break;
    Which will only end your app when that window is closed. Then experiment with closing the inner windows.
    Last edited by Cactus_Hugger; 06-02-2007 at 01:42 PM.
    long time; /* know C? */
    Unprecedented performance: Nothing ever ran this slow before.
    Any sufficiently advanced bug is indistinguishable from a feature.
    Real Programmers confuse Halloween and Christmas, because dec 25 == oct 31.
    The best way to accelerate an IBM is at 9.8 m/s/s.
    recursion (re - cur' - zhun) n. 1. (see recursion)

  5. #5
    Registered User Queatrix's Avatar
    Join Date
    Apr 2005
    Posts
    1,342
    Good point; My bad, sorry about that.

  6. #6
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    If you didn't want to use a global variable, you can use GetParent to check if the window is a top-level window:
    Code:
    	case WM_DESTROY:
    		if(GetParent(hWnd) == NULL) PostQuitMessage(0);
    		break;

  7. #7
    Registered User BraneMxm's Avatar
    Join Date
    Apr 2007
    Location
    Croatia
    Posts
    20

    It doesnt work

    Quote Originally Posted by anonytmouse View Post
    If you didn't want to use a global variable, you can use GetParent to check if the window is a top-level window:
    Code:
    	case WM_DESTROY:
    		if(GetParent(hWnd) == NULL) PostQuitMessage(0);
    		break;

    All the widnows close despite the changes i have made!

    Thanks
    Last edited by BraneMxm; 06-03-2007 at 04:32 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. process programming
    By St0rM-MaN in forum Linux Programming
    Replies: 2
    Last Post: 09-15-2007, 07:53 AM
  2. Adding colour & bmps to a Win 32 Window??
    By carey_sizer in forum Windows Programming
    Replies: 4
    Last Post: 09-04-2004, 05:55 PM
  3. opengl help
    By heat511 in forum Game Programming
    Replies: 4
    Last Post: 04-05-2004, 01:08 AM
  4. MFC :: Finding Child Window of a CWnd* Object?
    By SyntaxBubble in forum Windows Programming
    Replies: 2
    Last Post: 09-06-2003, 09:06 AM
  5. opengl code not working
    By Unregistered in forum Windows Programming
    Replies: 4
    Last Post: 02-14-2002, 10:01 PM