how can I move and/or completely delete the Buttons
OK, Cancel, Apply or Help from a property sheet dialog.?
Something like this:
hWndOK = GetDlgItem(hWnd, IDOK);
DestroyWindow(hWndOK
in the INITDIALOG doesn't work.
An how can I modify the room between the sheets
and the border of the dialog (to fit my other program layout)
Additional how can I add more space to the PropertySheetDIALOG
(not the sheets) to add a common element (eg. tree view) for all
sheets, not just one sheet?
Finally: It si possible to hide the tabs of the tab-control?
perhaps to add a custom navigation through the tabs
(eg. tree)?
Thomas
> how can I move and/or completely delete the Buttons
> OK, Cancel, Apply or Help from a property sheet dialog.?
You can do anything on PSCB_INITIALIZED notification (hide, move, etc)
>> how can I move and/or completely delete the Buttons
>> OK, Cancel, Apply or Help from a property sheet dialog.?
>
> You can do anything on PSCB_INITIALIZED notification (hide, move, etc)
Great, seems that this was the key hint for me. But still
have a problem with the pfnCallback function and _HOW_ to
code and call that function?
The structure says it is not a fuction Pointer like the pfnDlgProc member.
But passing the concrete Message "PSCB_INITIALIZED" while the PSP
is initializing can't be right. But what do I have to do now? I don't find a
usefull
example by MSDN or Web and its still not working :-(
If I debug the App, the function "PropSheetProc" is called when the
PSP is initializing. But the Button still exist after creation-
Please have a look at these two functions:
HWND CreatePropertySheet(HWND hWndOwner, struct MyDATA *pDat)
{
PROPSHEETPAGE psp[3];
PROPSHEETHEADER psh = {0};
psp[0].dwSize = sizeof(PROPSHEETPAGE);
psp[0].dwFlags = PSP_USETITLE | PSP_PREMATURE | PSH_USECALLBACK;
psp[0].hInstance = GetModuleHandle(0);
psp[0].pszTemplate = (LPCSTR)MAKEINTRESOURCE(IDD_PP_COMMON);
psp[0].pszIcon = NULL;
psp[0].pfnDlgProc = PsDataInputProc;
psp[0].pszTitle = TEXT(STR_PP_COMMON);
psp[0].lParam = (LPARAM)pDat;
/*psp[0].pfnCallback = PropSheetProc;*/
psp[0].pfnCallback = (LPFNPSPCALLBACK)PropSheetProc(hWndOwner,
PSCB_INITIALIZED, 0);
/*psp[1].dwSize = sizeof(PROPSHEETPAGE);*/
/*psp[2].dwSize = sizeof(PROPSHEETPAGE);*/
psh.dwSize = sizeof(PROPSHEETHEADER);
psh.dwFlags = PSH_PROPSHEETPAGE;
psh.hwndParent = hWndOwner;
psh.hInstance = GetModuleHandle(0);
psh.pszIcon = NULL;
psh.pszCaption = (LPCSTR)TEXT("Options");
psh.nPages = sizeof(psp)/sizeof(PROPSHEETPAGE);
psh.ppsp = (LPCPROPSHEETPAGE)&psp;
return (HWND)PropertySheet(&psh);
}
int CALLBACK PropSheetProc(HWND hWnd, UINT uMsg, LPARAM lParam)
{
HWND hWndOK = NULL;
switch( uMsg )
{
case PSCB_INITIALIZED:
hWndOK = GetDlgItem(hWnd, PSBTN_OK);
DestroyWindow(hWndOK);
return (INT_PTR)TRUE; /* PSCB_INITIALIZED */
case PSCB_PRECREATE:
return (INT_PTR)TRUE; /* PSCB_PRECREATE */
case PSCB_BUTTONPRESSED:
return (INT_PTR)TRUE; /* PSCB_BUTTONPRESSED */
}
return (INT_PTR)FALSE; /* uMsg */
}
Do you know where and what is my misstake?
Hope that someone knows this. Because I don't find
an appropriate example.
Do I have to implement the "PropSheetPageProc" too?
Thomas
PS: For a complete reference the pfnDlgProc
BOOL APIENTRY PsDataInputProc(HWND hWnd, UINT uMsg, UINT wParam, LONG
lParam)
{
int wmId = 0;
int wmEvent = 0;
PROPSHEETPAGE *ps;
struct MyDATA * pDat;
pDat = (struct MyDATA *)GetWindowLongPtr(hWnd, GWL_USERDATA);
switch( uMsg )
{
case WM_INITDIALOG:
ps = (PROPSHEETPAGE *)lParam;
pDat = (struct MyDATA *)ps->lParam;
SetWindowLongPtr(hWnd, GWL_USERDATA, (LONG_PTR)pDat);
/* CODE */
return TRUE;
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
/* parse the WM_COMMAND selections */
switch( wmId )
{
case IDC_RADIO_BUTTON1:
/* CODE */
return (INT_PTR)TRUE;
default:
break; /* wmId */
}
return (INT_PTR)FALSE; /* WM_COMMAND */
case WM_NOTIFY:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
switch( wmId )
{
case IDC_TREE_OPTIONS:
switch( ((LPNMHDR)lParam)->code )
{
case TVN_SELCHANGED:
/* CODE */
return (INT_PTR)TRUE;
default:
break; /* ((LPNMHDR)lParam)->code */
}
return (INT_PTR)FALSE; /* IDC_TREE_OPTIONS */
default:
break; /* wmId */
}
switch( ((NMHDR FAR *)lParam)->code )
{
case PSN_SETACTIVE:
break;
case PSN_APPLY: /* OK, CANCEL or APPLY */
/*if( AllOk() ) {*/
if( TRUE ) {
SetWindowLong(hWnd, DWL_MSGRESULT, PSNRET_NOERROR);
}else {
SetWindowLong(hWnd, DWL_MSGRESULT,
PSNRET_INVALID_NOCHANGEPAGE);
}
return TRUE;
case PSN_KILLACTIVE: /* if page changed or OK is pressed */
SetWindowLong(hWnd, DWL_MSGRESULT, FALSE);
return 1;
case PSN_RESET: /* all changes since last PSN_APPLY will be lost */
SetWindowLong(hWnd, DWL_MSGRESULT, FALSE);
break;
}
return (INT_PTR)TRUE; /* WM_NOTIFY */
}
return FALSE;
}
> Great, seems that this was the key hint for me. But still
> have a problem with the pfnCallback function and _HOW_ to
> code and call that function?
Set the callback for PROPSHEETHEADER :
psh.dwFlags = PSH_PROPSHEETPAGE |PSH_USECALLBACK;
psh.pfnCallback = (PFNPROPSHEETCALLBACK)PropSheetProc;
then
hWndOK = GetDlgItem(hWnd, IDOK);
As I described in my last post I already have added the dwFlag
PSH_USECALLBACK and implemented the PropSheetProc
decirbed here:
http://msdn.microsoft.com/en-us/library/bb760815(VS.85).aspx
and tried various IDs (IDOK and PSBTN_OK) using GetDlgItem
and DestroyWindow() in the PSCB_INITIALIZED Message
but the button still exist.
btw: If I implement it like you described above like
psh.pfnCallback = (PFNPROPSHEETCALLBACK)PropSheetProc;
The callback function is never reached. Even if the PSH_USECALLBACK
was given to the dwFlag member.
btw2: If I implement it like that:
psp[0].pfnCallback = (LPFNPSPCALLBACK)
PropSheetProc(hWndOwner, PSCB_INITIALIZED, 0);"
the callback function is reached, but has no effect.
Waht is wrong. I dont't understand that. :-(
Thomas
> psh.pfnCallback = (PFNPROPSHEETCALLBACK)PropSheetProc;
>
> The callback function is never reached. Even if the PSH_USECALLBACK
> was given to the dwFlag member.
I just add :
psh.dwFlags = PSH_PROPSHEETPAGE |PSH_USECALLBACK;
psh.pfnCallback = (PFNPROPSHEETCALLBACK)PropSheetProc;
to the MSDN sample props.c (Nancy CLUTS)
and it works for me (test on XP)...
>> [...]
> I just add :
>
> psh.dwFlags = PSH_PROPSHEETPAGE |PSH_USECALLBACK;
> psh.pfnCallback = (PFNPROPSHEETCALLBACK)PropSheetProc;
>
> to the MSDN sample props.c (Nancy CLUTS)
> and it works for me (test on XP)...
hmm, I have vista. But that shouldn't be a problem.
And it's not just working - you can delete the default buttons?
Can you post (or email me) your complete code?
Do you have a link to the example props.c by Nancy Cluts ?
Can't find that at MSDN and I'm going crauy about this code ;-)
Thomas
> Do you have a link to the example props.c by Nancy Cluts ?
> Can't find that at MSDN and I'm going crauy about this code ;-)
I've uploaded original sources :
http://myfreefilehosting.com/f/49ee102732_1.26MB
Thanx. The code looks a littele bit strange to me ;-)
But I solved the problem and got it...
Last Question about this. ;-)
How can I destroy/remove/hide the _disabled_ Apply button
in a property sheet.
I know "GetDlgItem()". But everybody in the net talks
about CPropertySheet, But I use pure and strict C code and the
ID_APPLY_NOW isn't defined. I can't finde the appropriate header :-(
I always get the error:
Error 1 error C2065: 'ID_APPLY_NOW' : undeclared identifier d:\active\test.c
1202 test
Does anybod knows that an how to remove that disabled button?
btw: I think it's a problem to remove a disabled Item, isn't it?
I also tried this:
hWndCancel = GetDlgItem(hWnd, IDCANCEL);
hWndApply = GetNextDlgGroupItem(hWnd, hWndCancel, FALSE);
DestroyWindow(hWndApply);
But the strange thing is, that the next item is the OK Button.
Anyway I can't get and don't know the ID of the Apply Button and
it is definitely _NOT_ the ID_APPLY_NOW :-(
Thomas
> Does anybod knows that an how to remove that disabled button?
> btw: I think it's a problem to remove a disabled Item, isn't it?
>
> I also tried this:
>
> hWndCancel = GetDlgItem(hWnd, IDCANCEL);
> hWndApply = GetNextDlgGroupItem(hWnd, hWndCancel, FALSE);
> DestroyWindow(hWndApply);
>
> But the strange thing is, that the next item is the OK Button.
> Anyway I can't get and don't know the ID of the Apply Button and
> it is definitely _NOT_ the ID_APPLY_NOW :-(
Normally,
hWndApply = GetDlgItem(hWnd, 0x3021);
>>> [...]
>> But the strange thing is, that the next item is the OK Button.
>> Anyway I can't get and don't know the ID of the Apply Button and
>> it is definitely _NOT_ the ID_APPLY_NOW :-(
>
> Normally,
> hWndApply = GetDlgItem(hWnd, 0x3021);
Yes, that is what I found. Do you know where this is defined?
Is it always 12321 ?
Thomas
> Yes, that is what I found. Do you know where this is defined?
> Is it always 12321 ?
It's mainly defined in atlres.h
http://www.koders.com/c/fidC3413AC3DA92F46CB79680DAB4566552CF9E4F32.aspx
>> Yes, that is what I found. Do you know where this is defined?
>> Is it always 12321 ?
>
> It's mainly defined in atlres.h
> http://www.koders.com/c/fidC3413AC3DA92F46CB79680DAB4566552CF9E4F32.aspx
Thank you for your help. Was very usefull.
I found today the PSH_NOAPPLYNOW flag which is probably the
best way to remove the apply button ;-)
Now I have a problem to point to my userdata and Get/SetWindowLongPtr
doesn't really work.
In the CreatePropertySheet function where I define the PSPs and the
PSP Header I set my user Data with:
SetWindowLongPtr(hWndOwner, GWL_USERDATA, (LONG_PTR)pDat);
psh.pfnCallback = (PFNPROPSHEETCALLBACK)PropSheetProc;
In the PropSheetProc funtion I need the Data, but don't know how to cast
the Pointer. Have the follwing code.
int CALLBACK PropSheetProc(HWND hWnd, UINT uMsg, LPARAM lParam)
{
PROPSHEETPAGE *ps;
PROPSHEETHEADER *psh;
struct MyDATA * pDat;
pDat = (struct MyDATA *)GetWindowLongPtr(hWnd, GWL_USERDATA);
switch( uMsg )
{
case PSCB_INITIALIZED:
pDat = (struct MyDATA *)lParam;
SetWindowLongPtr(hWnd, GWL_USERDATA, (LONG_PTR)pDat);
But this code doesn't work like in other DialogProcs, bcause the lParam
holds
a Template for the Resource of the Dialog.
Does anybody know how to get my user data?
Thomas