Compilerfehler mit Tabcontrol[ERLEDIGT] Neues Problem...



  • Musst in der WinApi-Beschreibung nachlesen, wie CreateDialog() aufgerufen werden muss. Der Compiler meckert den 4.Parameter an. Doch warum so? Dialoge kann man ohne CreateDialog() einfacher in einer Ressource (*.rc) unterbringen. Das macht für Anfänger weniger Mühe!



  • Also wie gesagt, dass Problem hab ich gelöst. Nur mir gefällt die Arbeit mit Dialogen eigentlich gar nich. Ich will meine Fenster lieber von Hand erstellen^^



  • Was willst Du nun genau - Fenster, Dialog (ist auch ein Fenster) oder nur in einer Anwendung die TAB-Taste selbst abfragen? Teile am besten das Ziel mit, das Du verfolgst.



  • Ok mal ne kurze Beschreibung:
    Es soll ein Programm für ein Spiel werden. In diesem Programm will ich mehrere Teilprogramme einbauen, zwischen denen man mit den registerkarten wechseln kann. Z.B. ein Registerkarte für eine Art Datenbank. Eine für Quests, usw.
    Ich hab mit dem programm auch schon angefangen aber hab bisher halt nur ein "Modul" drin. Da hab ich bisher alles über

    case WM_CREATE:
                hwndbutton2 = CreateWindow ( "button", "dialog2",
                                       WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
                                       20, 20, 130, 50, hWnd, (HMENU)1,
                                       (HINSTANCE) GetWindowLong (hWnd, GWL_HINSTANCE), NULL);
    

    erstellt. Und so würde ich das auch gern weiterhin machen. Wenn ich nun aber das tabcontrol verwenden will wie es auf winapi.net beschrieben wird, sehe ich halt nur den Dialog den ich über den resourcen editor erstellt habe. Was ich in den jeweiligen Prozeduren über createwindow erstelle sehe ich nicht.

    Also ich will einfach nur meine Fenster ohne Dialoge gestalten. Und dann zwischen ihnen hin und her wechseln.



  • Kann mir da keiner helfen?



  • Noch einmal zum besseren Verständnis für mich und andere: Du willst über die TAB-Taste (oder was ist bei Dir ein Tabcontrol?) zwischen verschiedenen Fenstern ohne Dialoge umschalten können. Habe ich das richtig verstanden? Nun gut, die TAB-Taste wird von Windows selbst verwaltet, z.B. für Editfelder in Dialogen. Wenn Du also irgendwo eine eigene Leistung des Programmes haben willst, wo Windows nichts vorgesehen hat, dann bleibt nur der Weg, eine Fensterunterklasse (subclass) mit einer eigenen SubclassProc einzurichten. Hier kannst Du alles vor Windows abfangen und bestimmen, was gemacht werden soll. Den Rest machst Du dann mit SendMessage(hwndXXX,...) an Deine beteilgten Fenster. Vielleicht hilft Dir das weiter.



  • Nein mit tabcontrol meine ich nicht die tab taste sondern das steuerelement tabcontrol. Also das man registerkarten benutzen kann.

    So etwa:
    http://www.axure.com/images/au-dynamicpanels_tabcontrol.gif

    Und zwischen denen kann ich hin und her schalten in dem ich Dialoge erstelle und beim wechseln von einem Tab zum andern den alten ausblende und den neuen anzeigen lasse. Mein Problem bei der Sache ist nur das ich das was ich von hand im quellcode an edit fenstern, buttons und co. erstelle nicht sehen kann weil da die dialoge vor sind.



  • Grabgewalt schrieb:

    Was ich in den jeweiligen Prozeduren über createwindow erstelle sehe ich nicht.

    Blöde Frage: Hast du denn auch ShowWindow(SW_SHOW) verwendet? Du musst eigentlich nur die jeweiligen Controls anzeigen/verstecken, je nachdem welcher Tab gerade gedrückt wurde.

    P.S.: Cooler Nickname! Fürsten-Fan?

    EDIT: Oh, moment mal. Du erzeugst verschiedene Controls und zeigst irgendwelche Dialoge an? Heißt das, diese Controls sind keine Kinder der "Tab-Dialoge"? Das sollten sie dann wohl sein.



  • Ja also Grabnebelfürsten war so ziemlich die erste Band aus dem Bereich BlackMetal die ich gehört habe und sind abgesehen vom 3. Album immer noch sehr nett.

    So zum Thema. Also ich hab wie gesagt das Tutorial von winapi.net komplett übernommen. Da wird halt mit Dialogen gearbeitet. Aber im grunde bräuchte ich doch nur beim TabWechsel die Prozedur wechseln und alle "alten" Controls ausblenden und die neuen einblenden, richtig? Dann kann ich die Dialoge doch komplett weglassen oder nicht? Oder geb ich den selbst erzeugten controls den handle des jeweiligen Dialogs so dass die dann auf den Dialogen angezeigt werden? Das würde ich einfacher finden. Dann könnte man ja leere Dialoge erzeugen auf denen ich dann selbst controls als childs den Dialoges erstelle über createwindow() und könnte den Rest so lassen wie ichs jetzt hab.

    Auch wenns ziemlich lang ist, aber vielleicht hat jemand lust mal zu gucken. Is halt im wesentlichen das tutorial von winapi.net:

    #include <windows.h>
    #include <commctrl.h>
    #include <tchar.h>
    #include <uxtheme.h>
    #include "resource.h"
    
    LRESULT CALLBACK WndProc(HWND, UINT , WPARAM, LPARAM);
    HRESULT WINAPI MyEnableThemeDialogTexture(HWND, DWORD );
    
    int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE, LPTSTR, int nCmdShow)
    {
      INITCOMMONCONTROLSEX iccex;
      WNDCLASSEX           wc;
      HWND                 hWnd;
      MSG                  msg;
    
        // Ohne CommonControls kein TabCtrl ...
        iccex.dwSize = sizeof(iccex);
        iccex.dwICC  = ICC_TAB_CLASSES;
        InitCommonControlsEx(&iccex);
    
        wc.cbSize        = sizeof(wc);
        wc.style         = 0;
        wc.lpfnWndProc   = WndProc;
        wc.cbClsExtra    = 0;
        wc.cbWndExtra    = 0;
        wc.hInstance     = hInstance;
        wc.hIcon         = (HICON)LoadIcon(NULL, IDI_APPLICATION);
        wc.hCursor       = (HCURSOR)LoadCursor(NULL, IDC_ARROW);
        wc.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE + 1);
        wc.lpszMenuName  = NULL;
        wc.lpszClassName = TEXT("TabCtrl-Test");
        wc.hIconSm       = (HICON)LoadIcon(NULL, IDI_APPLICATION);
    
        if(!RegisterClassEx(&wc))
            return(0);
        if(NULL == (hWnd = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW | WS_EX_APPWINDOW, 
                              wc.lpszClassName, wc.lpszClassName, WS_OVERLAPPEDWINDOW, 
                              CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 
                              NULL, NULL, hInstance, NULL)))
            return(0);
    
        ShowWindow(hWnd, nCmdShow);
    
        while(GetMessage(&msg, NULL, 0, 0))
        {
            if(!IsDialogMessage(hWnd, &msg))
            {
                TranslateMessage(&msg);
                DispatchMessage (&msg);
            }
        }
    
      return(msg.wParam);
    }
    
    INT CALLBACK DlgProc1(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
    	HWND hwndbutton;
        switch(uMsg)
        {
            case WM_CREATE: //Was ich hier mach wird halt nichts angezeigt
    			     hwndbutton = CreateWindow ( "button", "dialog1",
                                       WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
                                       50, 50, 130, 50, hWnd, (HMENU)1,
                                       (HINSTANCE) GetWindowLong (hWnd, GWL_HINSTANCE), NULL);
    
                 return(0);		 
          }
      return(DefWindowProc(hWnd, uMsg, wParam, lParam));
    }
    
    INT CALLBACK DlgProc2(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
    	HWND hwndbutton2;
        switch(uMsg)
        {
            case WM_CREATE: //Hier genauso
                hwndbutton2 = CreateWindow ( "button", "dialog2",
                                       WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
                                       20, 50, 130, 50, hWnd, (HMENU)2,
                                       (HINSTANCE) GetWindowLong (hWnd, GWL_HINSTANCE), NULL);
                 return(0);		 
          }
      return(DefWindowProc(hWnd, uMsg, wParam, lParam));
    }
    
    LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
      TCITEM item;
      HWND*  phDlg;
      HWND   hWndTemp;
      RECT   rc;
      int    nCurSel;
    
        switch(uMsg)
        {
            case WM_CREATE:
                 // TabCtrl erstellen und initialisieren
                 hWndTemp = CreateWindowEx(0, WC_TABCONTROL, TEXT(""), 
                                           WS_CHILD|WS_VISIBLE|WS_TABSTOP|
                                           WS_CLIPSIBLINGS|TCS_FOCUSNEVER|TCS_SINGLELINE, 
                                           0, 0, 0, 0, hWnd, (HMENU)IDC_TAB, 
                                           ((LPCREATESTRUCT)lParam)->hInstance, NULL);
                 SendMessage(hWndTemp, WM_SETFONT, 
                             (WPARAM)GetStockObject(DEFAULT_GUI_FONT), 0);
    
                 ZeroMemory(&item, sizeof(item));
                 item.mask    = TCIF_TEXT;
    
                 item.pszText = TEXT("Dialog 1");
                 TabCtrl_InsertItem(hWndTemp, 0, &item);
                 item.pszText = TEXT("Dialog 2");
                 TabCtrl_InsertItem(hWndTemp, 1, &item);
    
                 // Dialoge, die im TabCtrl erscheienen sollen, erzeugen
                 phDlg    = new HWND[2];
                 phDlg[0] = CreateDialog(((LPCREATESTRUCT)lParam)->hInstance, 
                    MAKEINTRESOURCE(IDD_DIALOG1), hWnd, DlgProc1);
                 phDlg[1] = CreateDialog(((LPCREATESTRUCT)lParam)->hInstance, 
                    MAKEINTRESOURCE(IDD_DIALOG2), hWnd, DlgProc2);
    
                 // Die Dialoge und das TabCtrl sind Geschwister. Da das TabCtrl
                 // aber zuerst erstellt wurde, liegt es ?ber den Dialogen. Damit
                 // es nicht zu Darstellungsproblemen kommt, ist sicherzustellen,
                 // das die Dialoge ueber dem TabCtrl liegen. Das leisten die
                 // folgenden BringWindowToTop-Aufrufe.
                 //
                 // Schaut Euch das auch mit dem Spy++ an und vergleicht die Reihenfolge
                 // der Fenster mit diesen Aufrufen mit der Reihenfolge ohne diesen Aufrufen
                 // Wer den Spy++ nicht hat, kann alternativ ein anderes Tool benutzen, z.B.:
                 // http://www.windows-spy.com/
                BringWindowToTop(phDlg[1]);
                BringWindowToTop(phDlg[0]);
    
                 // Dialoge in TabCtrls haben unter Windows XP ein
                 // anderes Aussehen als Dialoge, die nicht in einem
                 // TabCtrl sitzen. Hier wird die Version des Tabs
                 // getestet und bei Bedarf die Dialog entsprechend
                 // angepasst (die Funktion MyEnableThemeDialogTexture
                 // findet sich weiter unten)
                 if(SendMessage(hWndTemp, CCM_GETVERSION, 0, 0) >= 6)
                 {
                     MyEnableThemeDialogTexture(phDlg[0], ETDT_ENABLETAB);
                     MyEnableThemeDialogTexture(phDlg[1], ETDT_ENABLETAB);
                 }
    
                 // Handles der Child-Dialoge speichern
                 SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)phDlg);
                 return(0);
    
    			     case WM_NOTIFY:
                 switch(((LPNMHDR)lParam)->code)
                 {
                     case TCN_SELCHANGING:
                          // Diese Notification wird gesendet, *bevor* das TabCtrl
                          // die Auswahl aendert. Das ist ein guter Zeitpunkt, um
                          // den zurzeit angezeigten Dialog zu verstecken
                          phDlg   = (HWND*)GetWindowLongPtr(hWnd, GWLP_USERDATA);
                          nCurSel = TabCtrl_GetCurSel(((LPNMHDR)lParam)->hwndFrom);
    
                          if(0 == nCurSel)
                              ShowWindow(phDlg[0], SW_HIDE);
                          else if(1 == nCurSel)
                              ShowWindow(phDlg[1], SW_HIDE);
    
                          return(FALSE);
                     case TCN_SELCHANGE:
                          // Diese Notification wird gesendet, *nachdem* das TabCtrl
                          // die Auswahl geaendert hat. Dies ist ein guter Zeitpunkt,
                          // um den zur Auswahl passenden Dialog anzuzeigen
                          phDlg   = (HWND*)GetWindowLongPtr(hWnd, GWLP_USERDATA);
                          nCurSel = TabCtrl_GetCurSel(((LPNMHDR)lParam)->hwndFrom);
    
                          if(0 == nCurSel)
                              ShowWindow(phDlg[0], SW_SHOW);
                          else if(1 == nCurSel)
                              ShowWindow(phDlg[1], SW_SHOW);
    
                          return(0);
                     default:
                          break;
                 }
                 break;
    
    			        case WM_SIZE:
                 phDlg    = (HWND*)GetWindowLongPtr(hWnd, GWLP_USERDATA);
                 hWndTemp = GetDlgItem(hWnd, IDC_TAB);
    
                 // Das TabCtrl ueberdeckt die komplette Client-Area
                 SetRect(&rc, 0, 0, LOWORD(lParam), HIWORD(lParam));
                 MoveWindow(hWndTemp, 0, 0, rc.right, rc.bottom, TRUE);
    
                 // TCM_ADJUSTRECT berechnet die Display-Area des TabCtrls aus
                 // den Koordinaten, die bereits in rc stehen. Die Werte in der
                 // RECT-Struktur sind nach Rueckkehr entsrechend geaendert
                 SendMessage(hWndTemp, TCM_ADJUSTRECT, (WPARAM)FALSE, (LPARAM)&rc);
                 MoveWindow(phDlg[0], rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, TRUE);
                 MoveWindow(phDlg[1], rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, TRUE);
    
                 return(0);
    
            case WM_NCDESTROY:
                 // Das per new angeforderte Array muss natuerlich auch wieder
                 // geloescht werden.  ;-)
                 phDlg = (HWND*)GetWindowLongPtr(hWnd, GWLP_USERDATA);
                 delete [] phDlg;
                 PostQuitMessage(0);
                 return(0);
            default:
                 break;
        }
    
      return(DefWindowProc(hWnd, uMsg, wParam, lParam));
    }
    
     //Hier werden die Dialoge f?r das TabCtrl vorbereitet.
    typedef HRESULT (WINAPI * ENABLETHEMEDIALOGTEXTURE)(HWND, DWORD);
    
    HRESULT WINAPI MyEnableThemeDialogTexture(HWND hWnd, DWORD dwFlags)
    {
      ENABLETHEMEDIALOGTEXTURE pfnETDT;
      HINSTANCE                hDll;
      HRESULT                  hr;
    
        hr = HRESULT_FROM_WIN32(ERROR_CALL_NOT_IMPLEMENTED);
    
        if(NULL != (hDll = LoadLibrary(TEXT("uxtheme.dll"))))
        {
            if(NULL != (pfnETDT = (ENABLETHEMEDIALOGTEXTURE)GetProcAddress(hDll,
                                   "EnableThemeDialogTexture")))
            {
                hr = pfnETDT(hWnd, dwFlags);
            }
            FreeLibrary(hDll);
        }
    
      return(hr);
    }
    

    Ich hab grad nochmal geguckt. Ich glaub das Problem ist einfach das er gar nich ins switch meiner DlgProc1 und 2 kommt.



  • Omg ich glaub ich habs. Wenn ich in dlgproc1 und 2 anstatt wm_create wm_initdialog benutze werden meine buttons die ich da erzeuge angezeigt.



  • Da sag ich nur: C++, lang und steinig ist dein Weg!


Anmelden zum Antworten