Dialog im (Tab) Fenster Problemme



  • Hallo,

    ich hab wieder ein Problem. Ich möchte in einem TabControl ein Dialog anzeigen lassen, jenachdem welches Tab aktiviert ist. So, hab mit einem Dialog angefangen, und hab ich paar Probleme.

    1. Wenn die "DialogProc" Funktion "false" zurückgibt, dann hat der Dialog ein Fensterrahmen, seit dem Programmstart. Wenn er "true" zurückgibt, dann nicht.
    Hab mir blos einige Beispiele im Netz angeschaut und da geben diese Funtionen auch "false" zurück. Bei mir, wie gesagt, hat er dann ein Fensterrahmen.

    2. Mein Dialog hat zwei "RadioButtons" und ein "EditText". Die "RadioButtons" funktionieren normal, aber der "EditText" macht Problemme.
    Beim Programmstart ist er Fokusiert, kann da sofort was eintippen, aber die Markierung welche die Position anzeigt, die blinkt nicht (was unnormal ist).
    Und wenn ich z.B. die RadioButtons anklicke und möchte wieder was eingeben dann geht das nicht mehr. Kann "EditText" nicht mehr aktivieren. Hab das gefühl das ich durch klicke!

    Hier ist die Dialog Resource:

    // ...
    
    IDD_DIALOG_RENAME DIALOGEX 150, 70, 250, 100
    STYLE WS_CHILD | WS_VISIBLE | WS_EX_CONTROLPARENT
    CAPTION "Rename"
    FONT 8, "MS Sans Serif"
    BEGIN
        EDITTEXT        IDC_EDIT1, 11, 45, 98, 10, ES_AUTOHSCROLL | WS_BORDER
        LTEXT           "Name:", IDC_STATIC, 11, 35, 21, 8, SS_LEFT
        GROUPBOX        "Nummerrieren", IDC_STATIC, 11, 6, 110, 26
        RADIOBUTTON 	"Vor", IDC_RADIO1, 21, 17, 27, 8
        RADIOBUTTON 	"Nach", IDC_RADIO2, 87, 17, 32, 8
    END
    

    Und main.cpp:

    // ...
    
    HWND hDialogResult; // ist global
    
    // ...
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){
        // ...
    	// Tabs
    	hTab = CreateWindowEx(0, WC_TABCONTROL, "", 
    						  WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | WS_TABSTOP | TCS_FOCUSNEVER | TCS_SINGLELINE, 
    						  270, 50, 350, 450, 	
    						  hWnd, (HMENU) ID_TABCONTROL, hInstance, NULL);
    
    	MyCrateTabs(hTab);
    
    	hDialogResult = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_DIALOG_RENAME), hWnd, (DLGPROC) DialogProcRename);  
    
        // ...
    }
    

    Und hier die "DialogProc":

    LRESULT CALLBACK DialogProcRename(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam){
    
    	switch(uMsg){
    		case WM_INITDIALOG:
    			CheckDlgButton( hDlg, IDC_RADIO1, BST_UNCHECKED );
                CheckDlgButton( hDlg, IDC_RADIO2, BST_CHECKED );
    			break;
    		case WM_CLOSE:
    			DestroyWindow(hDlg);
    			return true;
    		case WM_DESTROY:
    			PostQuitMessage(0);
    			return true;
    		case WM_COMMAND:
    			switch(LOWORD(wParam)){
    				case IDC_EDIT1:
    					break;
    				case IDC_RADIO1:{
    					CheckRadioButton( hDlg, IDC_RADIO1, IDC_RADIO2, IDC_RADIO1 );
    					break;
    				}
    				case IDC_RADIO2:
    					CheckRadioButton( hDlg, IDC_RADIO1, IDC_RADIO2, IDC_RADIO2 );
    					break;
    			}
    			break;
    		default:
    			return true;
    	}
    	return true;
    }
    

    Hoffe ihr könnt mir helfen. 🙂



  • Wenn Du in einem Tab ein Dialog-Template anzeigen willst, dann musst Du eigentlich das hier machen:
    http://msdn.microsoft.com/en-us/library/windows/desktop/hh298366

    Und wann man warum "false" zurückliefert hängt immer von der entsprechenden Nachricht ab und ob man diese bearbeitet hat oder nicht...



  • Hallo ich bins wieder,

    hab das Beispiel von http://msdn.microsoft.com/en-us/library/windows/desktop/hh298366 nachgebaut.
    Soweit so gut, hab da noch ein "EditText" eingefügt und wieder das gleiche Probelm wie bei Punkt 2.

    Hier ist der komplette Programmcode:

    // main.rc
    #include <Windows.h>
    #include "resourse.h"
    
    IDD_DIALOG_DLG1 DIALOGEX 150, 70, 250, 100
    STYLE WS_CHILD | WS_EX_CONTROLPARENT | WS_VISIBLE
    CAPTION ""
    FONT 8, "MS Sans Serif"
    BEGIN
    	EDITTEXT        IDC_EDIT1, 30, 100, 98, 10, ES_AUTOHSCROLL | WS_BORDER
    	PUSHBUTTON      "Close", IDB_CLOSE1, 30, 30, 50, 14
    	PUSHBUTTON      "Test", IDB_TEST1, 100, 30, 50, 14
    END
    
    IDD_DIALOG_DLG2 DIALOGEX 150, 70, 350, 450
    STYLE WS_CHILD | WS_EX_CONTROLPARENT | WS_VISIBLE
    CAPTION ""
    FONT 8, "MS Sans Serif"
    BEGIN
    	PUSHBUTTON      "Close", IDB_CLOSE2, 30, 100, 50, 14
    	PUSHBUTTON      "Test", IDB_TEST2, 100, 100, 50, 14
    END
    
    // resourse.h
    #define IDD_DIALOG_DLG1		1000
    #define IDD_DIALOG_DLG2		2000
    #define IDC_EDIT1			3000
    #define IDB_CLOSE1			3001
    #define IDB_TEST1			3002
    #define IDB_CLOSE2			3003
    #define IDB_TEST2			3004
    
    #include <Windows.h>
    #include <commctrl.h>
    #include "resourse.h"
    
    typedef struct {
      WORD      dlgVer;
      WORD      signature;
      DWORD     helpID;
      DWORD     exStyle;
      DWORD     style;
      WORD      cDlgItems;
      short     x;
      short     y;
      short     cx;
      short     cy;
      //sz_Or_Ord menu;
      //sz_Or_Ord windowClass;
      WCHAR     title[100];
      WORD      pointsize;
      WORD      weight;
      BYTE      italic;
      BYTE      charset;
      //WCHAR     typeface[stringLen];
    } DLGTEMPLATEEX;
    
    char* cAppName = "Test";
    HINSTANCE hInst;
    
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    LRESULT CALLBACK DialogProc(HWND, UINT, WPARAM, LPARAM);
    DLGTEMPLATEEX* DoLockDlgRes(LPCTSTR);
    VOID OnSelChanged(HWND);
    
    #define C_PAGES 2 
    
    typedef struct tag_dlghdr { 
        HWND hwndTab;       // tab control 
        HWND hwndDisplay;   // current child dialog box 
        RECT rcDisplay;     // display rectangle for the tab control 
        DLGTEMPLATEEX *apRes[C_PAGES]; 
    } DLGHDR;
    
    // Handles the WM_INITDIALOG message for a dialog box that contains 
    //   a tab control used to select among three child dialog boxes.
    // Returns a result code.
    // hwndDlg - handle of the dialog box.
    // 
    HRESULT OnTabbedDialogInit(HWND hwndDlg) 
    { 
        INITCOMMONCONTROLSEX iccex;
        DWORD dwDlgBase = GetDialogBaseUnits();
        int cxMargin = LOWORD(dwDlgBase) / 4; 
        int cyMargin = HIWORD(dwDlgBase) / 8; 
    
        TCITEM tie; 
        RECT rcTab; 
        HWND hwndButton; 
        RECT rcButton; 
        int i; 
    
        // Initialize common controls.
        iccex.dwSize = sizeof(INITCOMMONCONTROLSEX);
        iccex.dwICC = ICC_TAB_CLASSES;
        //InitCommonControlsEx(&iccex);  Fehler	2	error LNK1120: 1 nicht aufgel÷ste Externe
    
        // Allocate memory for the DLGHDR structure. Remember to 
        // free this memory before the dialog box is destroyed.
        DLGHDR *pHdr = (DLGHDR *) LocalAlloc(LPTR, sizeof(DLGHDR)); 
    
        // Save a pointer to the DLGHDR structure in the window
        // data of the dialog box. 
        SetWindowLong(hwndDlg, GWL_USERDATA, (LONG) pHdr); 
    
        // Create the tab control. Note that g_hInst is a global 
        // instance handle. 
        pHdr->hwndTab = CreateWindow( 
            WC_TABCONTROL, "", 
            WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE, 
            0, 0, 100, 100, 
            hwndDlg, NULL, hInst, NULL 
            ); 
        if (pHdr->hwndTab == NULL) 
        {
            return HRESULT_FROM_WIN32(GetLastError());
        }
    
        // Add a tab for each of the three child dialog boxes. 
        tie.mask = TCIF_TEXT | TCIF_IMAGE; 
        tie.iImage = -1; 
        tie.pszText = "First"; 
        TabCtrl_InsertItem(pHdr->hwndTab, 0, &tie); 
        tie.pszText = "Second"; 
        TabCtrl_InsertItem(pHdr->hwndTab, 1, &tie); 
    
        // Lock the resources for the three child dialog boxes. 
        pHdr->apRes[0] = DoLockDlgRes(MAKEINTRESOURCE(IDD_DIALOG_DLG1)); 
        pHdr->apRes[1] = DoLockDlgRes(MAKEINTRESOURCE(IDD_DIALOG_DLG2));  
    
        // Determine a bounding rectangle that is large enough to 
        // contain the largest child dialog box. 
        SetRectEmpty(&rcTab); 
        for (i = 0; i < C_PAGES; i++) 
        { 
            if (pHdr->apRes[i]->cx > rcTab.right) 
                rcTab.right = pHdr->apRes[i]->cx; 
            if (pHdr->apRes[i]->cy > rcTab.bottom) 
                rcTab.bottom = pHdr->apRes[i]->cy; 
        }
    
        // Map the rectangle from dialog box units to pixels.
        MapDialogRect(hwndDlg, &rcTab);
    
        // Calculate how large to make the tab control, so 
        // the display area can accommodate all the child dialog boxes. 
        TabCtrl_AdjustRect(pHdr->hwndTab, TRUE, &rcTab); 
        OffsetRect(&rcTab, cxMargin - rcTab.left, cyMargin - rcTab.top); 
    
        // Calculate the display rectangle. 
        CopyRect(&pHdr->rcDisplay, &rcTab); 
        TabCtrl_AdjustRect(pHdr->hwndTab, FALSE, &pHdr->rcDisplay); 
    
        // Set the size and position of the tab control, buttons, 
        // and dialog box. 
        SetWindowPos(pHdr->hwndTab, NULL, rcTab.left, rcTab.top, 
                rcTab.right - rcTab.left, rcTab.bottom - rcTab.top, 
                SWP_NOZORDER); 
    
        // Move the first button below the tab control. 
        hwndButton = GetDlgItem(hwndDlg, IDB_CLOSE1); 
        SetWindowPos(hwndButton, NULL, 
                rcTab.left, rcTab.bottom + cyMargin, 0, 0, 
                SWP_NOSIZE | SWP_NOZORDER); 
    
        // Determine the size of the button. 
        GetWindowRect(hwndButton, &rcButton); 
        rcButton.right -= rcButton.left; 
        rcButton.bottom -= rcButton.top; 
    
        // Move the second button to the right of the first. 
        hwndButton = GetDlgItem(hwndDlg, IDB_TEST1); 
        SetWindowPos(hwndButton, NULL, 
            rcTab.left + rcButton.right + cxMargin, 
            rcTab.bottom + cyMargin, 0, 0, 
            SWP_NOSIZE | SWP_NOZORDER); 
    
        // Size the dialog box. 
        SetWindowPos(hwndDlg, NULL, 0, 0, 
            rcTab.right + cyMargin + (2 * GetSystemMetrics(SM_CXDLGFRAME)), 
            rcTab.bottom + rcButton.bottom + (2 * cyMargin)
            + (2 * GetSystemMetrics(SM_CYDLGFRAME)) 
            + GetSystemMetrics(SM_CYCAPTION), 
            SWP_NOMOVE | SWP_NOZORDER); 
    
        // Simulate selection of the first item. 
        OnSelChanged(hwndDlg); 
    
        return S_OK;
    } 
    
    // Loads and locks a dialog box template resource. 
    // Returns the address of the locked dialog box template resource. 
    // lpszResName - name of the resource. 
    //
    DLGTEMPLATEEX* DoLockDlgRes(LPCTSTR lpszResName) 
    { 
        HRSRC hrsrc = FindResource(NULL, lpszResName, RT_DIALOG); 
    
        // Note that g_hInst is the global instance handle
        HGLOBAL hglb = LoadResource(hInst, hrsrc);  
        return (DLGTEMPLATEEX *) LockResource(hglb); 
    } 
    
    // Processes the TCN_SELCHANGE notification. 
    // hwndDlg - handle to the parent dialog box. 
    //
    VOID OnSelChanged(HWND hwndDlg) 
    { 
        // Get the dialog header data.
        DLGHDR *pHdr = (DLGHDR *) GetWindowLong( 
            hwndDlg, GWL_USERDATA); 
    
        // Get the index of the selected tab.
        int iSel = TabCtrl_GetCurSel(pHdr->hwndTab); 
    
        // Destroy the current child dialog box, if any. 
        if (pHdr->hwndDisplay != NULL) 
            DestroyWindow(pHdr->hwndDisplay); 
    
        // Create the new child dialog box. Note that g_hInst is the
        // global instance handle.
        pHdr->hwndDisplay = CreateDialogIndirect(hInst, 
            (DLGTEMPLATE *)pHdr->apRes[iSel], hwndDlg, (DLGPROC) DialogProc); 
    	UpdateWindow(hwndDlg);
        return;
    } 
    
    // Positions the child dialog box to occupy the display area of the 
    //   tab control. 
    // hwndDlg - handle of the dialog box.
    //
    VOID WINAPI OnChildDialogInit(HWND hwndDlg) 
    { 
        HWND hwndParent = GetParent(hwndDlg);
        DLGHDR *pHdr = (DLGHDR *) GetWindowLong( 
            hwndParent, GWL_USERDATA); 
        SetWindowPos(hwndDlg, NULL, pHdr->rcDisplay.left,
            pHdr->rcDisplay.top,//-2,
            (pHdr->rcDisplay.right - pHdr->rcDisplay.left),
            (pHdr->rcDisplay.bottom - pHdr->rcDisplay.top),
            SWP_SHOWWINDOW);
    
        return;
    }
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){
    
    	HWND hWnd;			// Handle des Fensters
    	MSG msg;			// Nachrichtenstruktur
    	WNDCLASSEX wc;		// Fensterklasse (struct)
    
    	// Fenster-Struktur anlegen
    	wc.cbSize			= sizeof(WNDCLASSEX);											// Größe der Struktur in Bytes
    	wc.style			= 0;															// Fensterstil
    	wc.lpfnWndProc		= WndProc;														// Zeiger auf Callback-Funktion
    	wc.cbClsExtra		= 0;															// selten
    	wc.cbWndExtra		= 0;															// selten
    	wc.hInstance		= hInstance;													// Instanz Fensterprozedur
    	wc.hIcon			= LoadIcon(NULL, IDI_APPLICATION);								// Fenster Icon (Startleiste)
    	wc.hCursor			= LoadCursor(NULL, IDC_ARROW);									// Fenster Cursor
    	wc.hbrBackground	= (HBRUSH) GetStockObject(WHITE_BRUSH);							// Hintergrundfarbe
    	wc.lpszClassName	= cAppName;														// Klassen Name zu Indetifizierung
    	wc.lpszMenuName		= NULL;															// Menu
    	wc.hIconSm			= LoadIcon(NULL, IDI_APPLICATION);								// Icon im Fenster
    
    	// Fenster-Klasse Registrieren/Anmelden (mit Anfangsadresse)
    	if(!RegisterClassEx(&wc)){
    		MessageBox(NULL, "Windows Register Error", "Error!", MB_ICONEXCLAMATION | MB_OK);
    		return 0;
    	}
    
    	// Fenster erzeugen
    	hWnd = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW,	// Erweiterter Fensterstil
    						  cAppName,					// Fenster Name
    						  cAppName,					// Fenster Titel
    						  WS_OVERLAPPEDWINDOW,		// Fensterart
    						  CW_USEDEFAULT,			// x
    						  CW_USEDEFAULT,			// y
    						  650,						// width
    						  650,						// height
    						  NULL,						// Parent
    						  NULL,						// ? Menu
    						  hInstance,				// Instanz
    						  NULL);					// Zeiger auf Parameter (MDI)
    
    	// Fenster anzeigen und zeichnen
    	ShowWindow(hWnd, iCmdShow);
    	UpdateWindow(hWnd);
    
    	// Nachrichten-Schleife
    	while(GetMessage(&msg, NULL, 0, 0) > 0){
    
    		TranslateMessage(&msg);		// Tastaturcode
    		DispatchMessage(&msg);		// Nachricht an die Prozedur senden
    	}
    
    	return msg.wParam;
    }
    
    // Prozedur für das Hauptfenster
    LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam){
    
        switch(iMsg){
    		case WM_CREATE:
    			OnTabbedDialogInit(hWnd);
    			return true;
    		case WM_NOTIFY:
    			switch(((LPNMHDR)lParam)->code){
    				case TCN_SELCHANGE:
    					OnSelChanged(hWnd);
    			}
    			break;
    
    		case WM_CLOSE:
    			DestroyWindow(hWnd);
    			break;
            case WM_DESTROY:
                PostQuitMessage(0);
                return 0;			
        }
        return DefWindowProc(hWnd, iMsg, wParam, lParam);
    }
    
    LRESULT CALLBACK DialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam){
    
    	switch(uMsg){
    		case WM_INITDIALOG:{
    			OnChildDialogInit(hDlg);
    			return true;
    		}
    	}
    	return true;
    }
    

Anmelden zum Antworten