#1
  1. Don't fear the penguins!
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2003
    Location
    arborlon.gingle.net
    Posts
    147
    Rep Power
    12

    Tabbed Dialogs in VC++


    Can someone please explain how I can add tabs to my dialog based app in Visual C++ 7.0? I can't seem to figured it out or find out how on the web... Thanks.
    Every morning, I get up and look through the Forbes list of the richest people in America. If I'm not there, I go to work.

    May your Tongue stick to the Roof of your Mouth with the Force of a Thousand Caramels.

    To the systems programmer, users and applications serve only to provide a test load.
  2. #2
  3. No Profile Picture
    Offensive Member
    Devshed Novice (500 - 999 posts)

    Join Date
    Oct 2002
    Location
    in the perfect world
    Posts
    622
    Rep Power
    28
    >>Can someone please explain how I can add tabs to my dialog based app in Visual C++ 7.0

    Do you mean a TAB control. Usually you have multiple dialogs hidden until their TAB is selected. ie as the TAB is changed on dlg is hidden and another is shown.

    Watch out for a bug in the MSVC v7 resource editor (2003, not sure of 2002).
    If you select the 'multi line' style the editor will actually add the 'owner draw' style causing your app to crash.
    Add the style manually by editing the script.rc file.
    The essence of Christianity is told us in the Garden of Eden history. The fruit that was forbidden was on the Tree of Knowledge. The subtext is, All the suffering you have is because you wanted to find out what was going on. You could be in the Garden of Eden if you had just kept your f***ing mouth shut and hadn't asked any questions.

    Frank Zappa
  4. #3
  5. Don't fear the penguins!
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2003
    Location
    arborlon.gingle.net
    Posts
    147
    Rep Power
    12
    Yeh that kind of tabs (aka property pages). I found a walkthough for it here [MSDN]. Seems sorta dated, but I figure that it ought to work. Of course, it does seem to be a kind of round about way to do it (to me at least). Would you happen to know of an easier method?


    Originally posted by TechNoFear Watch out for a bug in the MSVC v7 resource editor (2003, not sure of 2002).
    If you select the 'multi line' style the editor will actually add the 'owner draw' style causing your app to crash.
    Add the style manually by editing the script.rc file. [/B]
    Thanks for the heads up. Do you know if there is some sorta hotfix or somthing for this?
    Every morning, I get up and look through the Forbes list of the richest people in America. If I'm not there, I go to work.

    May your Tongue stick to the Roof of your Mouth with the Force of a Thousand Caramels.

    To the systems programmer, users and applications serve only to provide a test load.
  6. #4
  7. Don't fear the penguins!
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2003
    Location
    arborlon.gingle.net
    Posts
    147
    Rep Power
    12
    Can anyone tell me why this causes an exception whenever I try to do it? Its pretty much a slightly modified version of somthing I pulled off of MSDN here (down near the bottom) .

    Code:
    void DoPropertySheet(HWND hwndOwner, HINSTANCE hInst)
    {
        PROPSHEETPAGE pages[2];
        PROPSHEETHEADER PropHeader;
    
        pages[0].dwSize = sizeof(PROPSHEETPAGE);
        pages[0].dwFlags = PSP_USEICONID | PSP_USETITLE;
        pages[0].hInstance = hInst;
        pages[0].pszTemplate = MAKEINTRESOURCE(IDD_MAINDLG_EVENTS);
        pages[0].pszIcon = MAKEINTRESOURCE(IDI_EVENTS);
        //pages[0].pfnDlgProc = FontDialogProc;
        pages[0].pszTitle = MAKEINTRESOURCE(IDS_FONT)
        pages[1].pszTitle = (LPSTR)"Events";
        pages[0].lParam = 0;
        pages[0].pfnCallback = NULL;
        
        pages[1].dwSize = sizeof(PROPSHEETPAGE);
        pages[1].dwFlags = PSP_USEICONID | PSP_USETITLE;
        pages[1].hInstance = hInst;
        pages[1].pszTemplate = MAKEINTRESOURCE(IDD_MAINDLG_CONFIG);
        pages[1].pszIcon = MAKEINTRESOURCE(IDI_CONFIG);
        //pages[1].pfnDlgProc = BorderDialogProc;
        pages[1].pszTitle = MAKEINTRESOURCE(IDS_BORDER);
        pages[1].pszTitle = (LPSTR)"Configuration";
        pages[1].lParam = 0;
        pages[1].pfnCallback = NULL;
    
        PropHeader.dwSize = sizeof(PROPSHEETHEADER);
        PropHeader.dwFlags = PSH_USEICONID | PSH_PROPSHEETPAGE; 
        PropHeader.hwndParent = hwndOwner;
        PropHeader.hInstance = hInst;
        PropHeader.pszIcon = MAKEINTRESOURCE(IDI_ICON);
        PropHeader.pszCaption = (LPSTR)"PropSheet";
        PropHeader.nPages = sizeof(pages) / sizeof(PROPSHEETPAGE);
        PropHeader.nStartPage = 0;
        PropHeader.ppsp = (LPCPROPSHEETPAGE) &pages;
        PropHeader.pfnCallback = NULL;
     
        PropertySheet(&PropHeader);
        return;
    }
    I'm calling it with:

    Code:
    DoPropertySheet(NULL, hInst);
    Thanks for any help.
    Every morning, I get up and look through the Forbes list of the richest people in America. If I'm not there, I go to work.

    May your Tongue stick to the Roof of your Mouth with the Force of a Thousand Caramels.

    To the systems programmer, users and applications serve only to provide a test load.
  8. #5
  9. No Profile Picture
    Offensive Member
    Devshed Novice (500 - 999 posts)

    Join Date
    Oct 2002
    Location
    in the perfect world
    Posts
    622
    Rep Power
    28
    >>Do you know if there is some sorta hotfix or somthing for this?

    Yes. Edit the script.rc file and add the style manually.

    Why the property page causes a crash.
    It is always a good idea to clear the struct before use. Uninitialised cells can cause crashes, use

    ZeroMemory(&Struct, sizeof(STRUCTURE));
    Try,
    PSP_DLGINDIRECT and use the pResource and NOT the pszTemplate.
    If it wants a pointer to a char array (LPCSTR) then use a char array and set the element to this char array. That way the 4 byte pointer in the structure will have enough memory to hold the whole string.

    ie
    char sTitle[64]="Dlg Title.";

    PropertyPage[0].pszTitle=sTitle;

    This will also fix these typos

    pages[0].pszTitle = MAKEINTRESOURCE(IDS_FONT)
    pages[1].pszTitle = (LPSTR)"Events";//I think this will cause crash

    pages[1].pszTitle = MAKEINTRESOURCE(IDS_BORDER);
    pages[1].pszTitle = (LPSTR)"Configuration";

    ect

    the ownerhwnd and so the callback the dlg should use is also undefined.

    PropHeader.nPages = sizeof(pages) / sizeof(PROPSHEETPAGE);
    You hard code the number of pages in the array (2), hard code it here as well.
    The essence of Christianity is told us in the Garden of Eden history. The fruit that was forbidden was on the Tree of Knowledge. The subtext is, All the suffering you have is because you wanted to find out what was going on. You could be in the Garden of Eden if you had just kept your f***ing mouth shut and hadn't asked any questions.

    Frank Zappa
  10. #6
  11. Don't fear the penguins!
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2003
    Location
    arborlon.gingle.net
    Posts
    147
    Rep Power
    12
    Ok, I'm still pretty new to C++, so I dont exactly understand everything that your saying. But I've got it working now :). Here's what i have so far:

    Code:
    void DoPropertySheet(HWND hwndOwner, HINSTANCE hInst)
    {
        PROPSHEETPAGE psp[2];
        PROPSHEETHEADER psh;
        
    	ZeroMemory(&psp, sizeof(PROPSHEETPAGE));
    	ZeroMemory(&psh, sizeof(PROPSHEETHEADER));
    
    	TCHAR tszTitle0[] = "Events";
        TCHAR tszTitle1[] = "Configuration";
    	TCHAR tszCaption[] = "myApp v0.6";
    
        psp[0].dwSize = sizeof(PROPSHEETPAGE);
        psp[0].dwFlags = PSP_USEICONID | PSP_USETITLE;
        psp[0].hInstance = hInst;
        psp[0].pszTemplate = MAKEINTRESOURCE(IDD_MAINDLG_EVENTS);
        psp[0].pszIcon = NULL; 
        psp[0].pfnDlgProc = NULL;
        psp[0].pszTitle = tszTitle0;
        psp[0].lParam = 0;
        psp[0].pfnCallback = NULL;
    
        psp[1].dwSize = sizeof(PROPSHEETPAGE);
        psp[1].dwFlags = PSP_USEICONID | PSP_USETITLE;
        psp[1].hInstance = hInst;
        psp[1].pszTemplate = MAKEINTRESOURCE(IDD_MAINDLG_CONFIG);
        psp[1].pszIcon = NULL; 
        psp[1].pfnDlgProc = NULL;
        psp[1].pszTitle = tszTitle1;
        psp[1].lParam = 0;
        psp[1].pfnCallback = NULL;
    
        psh.dwSize = sizeof(PROPSHEETHEADER);
        psh.dwFlags = PSH_USEICONID | PSH_PROPSHEETPAGE;
        psh.hwndParent = hwndOwner;
        psh.hInstance = hInst;
        psh.pszIcon = NULL;
        psh.pszCaption = tszCaption;
        psh.nPages = sizeof(psp) / sizeof(PROPSHEETPAGE);
        psh.nStartPage = 0;
        psh.ppsp = (LPCPROPSHEETPAGE) &psp;
        psh.pfnCallback = NULL;
     
    	// Now do it and return
    	PropertySheet(&psh);
        return;
    }
    I think I understand the zeroing the memory and using character arrays for the titles/caption, but I'm not sure what you mean by

    ...
    PSP_DLGINDIRECT and use the pResource and NOT the pszTemplate.
    ...
    the ownerhwnd and so the callback the dlg should use is also undefined.
    ...
    You hard code the number of pages in the array (2), hard code it here as well.
    ...
    It works, but I'd still like to know what you meant by that :) Thanks for the help!
    Every morning, I get up and look through the Forbes list of the richest people in America. If I'm not there, I go to work.

    May your Tongue stick to the Roof of your Mouth with the Force of a Thousand Caramels.

    To the systems programmer, users and applications serve only to provide a test load.
  12. #7
  13. No Profile Picture
    Offensive Member
    Devshed Novice (500 - 999 posts)

    Join Date
    Oct 2002
    Location
    in the perfect world
    Posts
    622
    Rep Power
    28
    >>ZeroMemory(&psp, sizeof(PROPSHEETPAGE));

    should be one for each element ofthe array

    ZeroMemory(&psp[0], sizeof(PROPSHEETPAGE));
    ZeroMemory(&psp[1], sizeof(PROPSHEETPAGE));

    >>the ownerhwnd and so the callback the dlg should use is also undefined.

    The Owner hwnd determines where windows sends the childs messages ie which callback. A suggestion. Obviously there is no communication to the parents callback (you send in NULL as the owner hwnd).

    >>PSP_DLGINDIRECT and use the pResource and NOT the pszTemplate.

    Just a another way of doing the same thing. Not 100% sure where the error was so I offered some other suggestions to try.

    >>You hard code the number of pages in the array (2), hard code it here as well.

    #define PP_ARRAY_SIZE 2

    PROPSHEETPAGE psp[PP_ARRAY_SIZE]; // hard coded array size

    psh.nPages = sizeof(psp) / sizeof(PROPSHEETPAGE); //dynamically determine size

    or

    psh.nPages = PP_ARRAY_SIZE*sizeof(PROPSHEETPAGE); //hard coded size

    Only a question of style. I feel it is better to keep it simple.
    The essence of Christianity is told us in the Garden of Eden history. The fruit that was forbidden was on the Tree of Knowledge. The subtext is, All the suffering you have is because you wanted to find out what was going on. You could be in the Garden of Eden if you had just kept your f***ing mouth shut and hadn't asked any questions.

    Frank Zappa
  14. #8
  15. Don't fear the penguins!
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2003
    Location
    arborlon.gingle.net
    Posts
    147
    Rep Power
    12
    Thanks for the clarification and help!
    Every morning, I get up and look through the Forbes list of the richest people in America. If I'm not there, I go to work.

    May your Tongue stick to the Roof of your Mouth with the Force of a Thousand Caramels.

    To the systems programmer, users and applications serve only to provide a test load.

IMN logo majestic logo threadwatch logo seochat tools logo