2009-09-30 6 views
1

L'API PropertySheet vous permet de définir un PropSheetProc qui peut recevoir (sous Windows XP et les versions ultérieures) des messages lorsque vous appuyez sur le bouton OK ou Appliquer. Cela vous permet de faire un traitement lorsque l'un de ces boutons est cliqué.Comment répondre au bouton OK ou Appliquer d'une feuille de propriétés une fois les pages traitées?

Toutefois, ce gestionnaire est appelé avant les pages de propriétés individuelles reçoivent la notification PSN_APPLY via leurs procédures de dialogue respectives. Je veux faire mon traitement après ces notifications ont été traitées, de préférence sans hacks laids. Comment puis-je faire cela?

Contexte: Je stocker ma configuration en une seule struct, et les pages individuelles, chacune des parties de modifier ce struct quand ils sont appliqués. Ensuite, après que ces valeurs ont été écrites, je souhaite appliquer les paramètres du struct en une seule fois, au lieu de les appliquer de nouveau à chaque page de propriétés.

Répondre

2

Je fini par utiliser la fonction de rappel PropSheetProc pour capturer la poignée de fenêtre de feuille de propriétés, puis accrocher une procédure de fenêtre de sous-classe, comme ceci:

// This is not officially defined, but the whole world uses it. 
#define ID_APPLY_NOW 0x3021 

WNDPROC origWinProc; 

LRESULT CALLBACK MyWinProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { 
    // Call the original window procedure. 
    LRESULT retVal = CallWindowProc(origWinProc, hwndDlg, msg, wParam, lParam); 
    // Now, and only now, do our own stuff. 
    switch (msg) { 
    case WM_COMMAND: 
     switch (LOWORD(wParam)) { 
     case IDOK: 
     case ID_APPLY_NOW: 
      applyConfig(); 
      saveConfig(); 
      break; 
     } 
     break; 
    } 
    // Return the original winproc's result. 
    return retVal; 
} 

int CALLBACK myPropSheetProc(HWND hwndDlg, UINT msg, LPARAM lParam) { 
    switch (msg) { 
    case PSCB_INITIALIZED: 
     // Override the property sheet's window procedure with our own. 
     origWinProc = (WNDPROC)SetWindowLongPtr(hwndDlg, GWLP_WNDPROC, (LONG_PTR)&MyWinProc); 
     break; 
    } 
    return 0; 
} 

(Oui, j'utilise switch déclarations même s'il n'y a qu'un seul Je suis étrange comme ça.)

0

ne pourriez-vous pas simplement intercepter le message BL_CLICKED de WM_COMMAND pour IDs IDOK, IDAPPLY et IDCANCEL?

Utilisez-vous MFC? ou ATL?

Bien que je ne peux pas penser à une fois que je ne serais pas en mesure d'intercepter le BM_CLICKED ...

Edit: Hmm jamais utilisé les pages de propriétés grâce à cette fonction ... juste eu une lecture à travers elle. Avez-vous défini la fonction pfnCallback et le jeu d'indicateurs PSH_USECALLBACK?

Chaque page dispose également d'un proc de dialogue. Ne pouvez-vous pas intercepter l'ok, annuler et appliquer à partir de là aussi? Je pense que l'autre plan semble convenir plus, cependant.

+0

Je devrais le faire dans ma boucle principale de message, qui est dans une partie complètement indépendante de l'application. Et je ne suis même pas sûr que ces messages passent par là, car 'PropertySheet()' ne retourne pas tant que la boîte de dialogue de la feuille de propriétés n'est pas fermée. – Thomas

+0

@Edit: J'utilise le 'pfnCallback', et il est appelé juste bien, mais * avant * toutes les procédures de dialogue des feuilles de propriétés individuelles. Je veux faire des choses * après * tout cela a fait son travail. – Thomas

+0

Aucun MFC ou ATL à propos. – Thomas

0

Vous n'avez pas besoin d'appliquer la structure depuis l'intérieur de l'un des gestionnaires de dialogue. Donc, si sa feuille de propriétés modale, vous pourriez faire quelque chose de simple comme:

// Display the property sheet. 
PropertySheet(&theSheet); 
// The peroperty sheets PSN_APPLY notification sets this bool to true in the struct. 
if(theStruct.fApply) 
    ApplyTheStruct(&theStruct); 

Sinon, je ne comprends pas pourquoi, étant donné que le « struct » est tout simplement collecter les informations saisies dans les pages , vous ne modifiez pas la structure lorsque l'utilisateur interagit avec la page. Ignorez les messagespar page et appliquez la structure lorsque PropSheetProc est appelé. OU le rejeter totalement si la notification est PSN_CANCEL.

+0

Cela ne fonctionne pas. Si l'utilisateur clique sur Appliquer, les éléments doivent être appliqués, mais la fonction 'PropertySheet' ne renvoie pas encore. – Thomas

+0

La fonction PropertySheet enverra d'abord le message PSN_APPLY PRopSheetProc, puis à chaque page, puis il reviendra. La structure va maintenant être mise en place et vous pouvez l'appliquer? Est-il vraiment important d'appliquer la structure avant que la feuille de propriétés ne soit visiblement fermée? –

Questions connexes