Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » VC++ / MFC » 3 ??? zu TBN_SAVE/TBN_RESTORE

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
18.01.2006, 20:46 Uhr
overcast



Hallo zusammen,

bei der Umstellung meiner Win32 Software auf XP Optik (Toolbars, Manifesten etc.) bin ich auf ein neues Problem beim Speichern der Toolbars gestossen.
Ich poste bewusst im MFC-Forum, da das Problem a) hier auch mit den Klassenroutinen Save und Restore bestehen sollte und b) 95% aller Anwendungen mittlerweile in MFC geschrieben werden.

Das Problem ergibt sich beim Zusammenspiel zw. XP Manifesten (comctrl 6), den neuen Notify Handlern TBN_SAVE/TBN_RESTORE (ab comctrl 5.8) und der Meldung TBN_BEGINADJUST.

Die einzige existierende Informationsquelle dazu findet man bei MS selbst:
http://msdn.microsoft.com/library/default.asp?
url=/library/en-us/shellcc/platform/commctls/toolbar/toolbar_using.asp

Bislang nutzte ich die Message TB_SAVERESTORE, um Toolbars in die Registry abzulegen bzw. auszulesen.
Wird nun in der Anwenung ein XP Manifest genutzt, funktioniert das RESTORE nicht mehr, da die Bitmap-Indizes als -1 zurückgelesen werden.
Nach einiger Zeit bin ich darauf gestossen, dass ich im Notifiy Handler TBN_BEGINADJUST den Wert 1 zurückgab.
Obwohl lt. Microsoft die Funktion "No Return Value" hat, MUSS diese 0 zurueckliefern.

Danach versuchte ich, die neuen Handler zu implementieren.
Da ich weder globale noch anwenderspezifische Daten den Buttons hinzufügen möchte, habe ich folgenden Code benutzt:

TBBUTTON tbButtonMain[] = {
0, MN_OPEN, TBSTATE_ENABLED, BTNS_BUTTON , 0, 0, 0, 0,
1, MN_SAVE, TBSTATE_ENABLED , BTNS_BUTTON , 0, 0, 0, 1,
etc. }

case TBN_SAVE:
{
LPNMTBSAVE lpnmtb = (LPNMTBSAVE) lParam;
if( lpnmtb->iItem == -1) // first run to initialize data
{
// no global oder custom information to save
lpnmtb->pData = (DWORD*) GlobalAlloc(GPTR, lpnmtb->cbData);
lpnmtb->pCurrent = lpnmtb->pData;
}
else
{
lpnmtb->tbButton = tbButtonMain[lpnmtb->iItem];
}
return -1;
}

case TBN_RESTORE:
{
LPNMTBRESTORE lpnmtb = (LPNMTBRESTORE) lParam;
if( lpnmtb->iItem == -1) // first run to extract data
{
// no global oder custom information to retrieve
}
else
{
// Workaround to correct the invalid iBitmap member
lpnmtb->tbButton.iBitmap = tbButtonMain[lpnmtb->iItem].iBitmap;
}
return 0;
}

Der "Workaround to correct the invalid iBitmap member" beim RESTORE ist notwendig, da zwar die iCommand korrekt gelesen wird, jedoch als iBitmap -1 zurückkommt.

Somit sind mit den comctl32.dll ab 5.80 bzw. 6.0 (mit Manifesten) 2 Fragen offen:
1) warum macht ein "return 1" im Handler TBN_BEGINADJUST Probleme?
2) warum wird in TBN_RESTORE "iBitmap = -1" geliefert, obwohl bei TBN_SAVE der Wert und auch der erzeugte Registryeintrag ok ist?

Im gesamten Web gibt es zu den neuen Handlern keinen Sample Source und selbst die Durchsicht der comctl32 Sources half nicht weiter.

Freue mich auf rege Beteiligung und danke im Voraus für das Interesse,

Grüße,
Frank.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
22.01.2006, 01:43 Uhr
overcast



Hallo,

ein kleiner Nachtrag (diesmal mit Useraccount )
ich habe ein weiteres Problem bei Verwendung von Manifesten entdeckt
Bei Verwendung eines XP-Manifests wurden die Separator nicht korrekt restored.
Die Separator wurden mit iBitmap=0 definiert, was ohne Manifest problemlos funktioniert.


C++:

TBBUTTON tbButtonMain[] =
{
    0, 0, TBSTATE_ENABLED, BTNS_SEP, 0, 0, 0, -1,
    0, MN_OPEN, TBSTATE_ENABLED, BTNS_BUTTON , 0, 0, 0, 0,
    1, MN_SAVE, TBSTATE_ENABLED , BTNS_BUTTON , 0, 0, 0, 1,
    etc.
}




Auszug aus http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/commctls/toolbar/structures/tbbutton.asp


Zitat von MSDN:

"If the button is a separator, that is, if fsStyle is set to BTNS_SEP, iBitmap determines the width of the separator, in pixels. For information on selecting button images from image lists, see TB_SETIMAGELIST message."



Im Comctl32 Source kann man sehen, dass beim Wert und UND Verwendung eines Manifests eine Defaultbreite von 8 gesetzt wird.
Obwohl diese bei TBN_RESORE für BTNS_SEP auch zurückgeliefert wird, so wird sie nicht korrekt in der Toolbar dargestellt.

Lösung bzw. Workaround bei Verwendung von Manifesten:
Setzen des iBitmap Members von TBBUTTON für BTNS_SEP Elemente auf einen Defaultwert (ideal: ebenfalls 8).

Allerdings tappe ich weiterhin im Dunkeln, warum iBitmap für normale Buttons als -1 zurückgelesen wird, so dass ich hier einen Bug vermute.

Bis zur Lösung nutze ich also folgenden Code nebst Workaround:


C++:

case TBN_SAVE:
{
    LPNMTBSAVE lpnmtb = (LPNMTBSAVE) lParam;
    if( lpnmtb->iItem == -1)
    {
        lpnmtb->pData = (DWORD*) GlobalAlloc(GPTR,    lpnmtb->cbData);
        lpnmtb->pCurrent = lpnmtb->pData;
    }
    return 0;
}
    
case TBN_RESTORE:
{
    LPNMTBRESTORE lpnmtb = (LPNMTBRESTORE) lParam;
    if( lpnmtb->iItem != -1)
    {
        // Workaround to correct the invalid iBitmap member
        lpnmtb->tbButton.iBitmap = tbButtonMain[lpnmtb->iItem].iBitmap;
    }
    return 0;
}




Interessant ist auch die Tatsache, dass die MFC-Dokumentation für die TBBUTTON-Struktur andere Informationen liefert:


Zitat von MSDN:

Remarks
The lpButtons pointer points to an array of TBBUTTON structures. Each TBBUTTON structure associates the button being added with the button's style, image and/or string, command ID, state, and user-defined data:

typedef struct _TBBUTTON {
int iBitmap;// zero-based index of button image
int idCommand; // command to be sent when button pressed
BYTE fsState; // button state--see below
BYTE fsStyle; // button style--see below
DWORD dwData; // application-defined value
int iString;// zero-based index of button label string
} TBBUTTON;
The members are as follows:

iBitmap
Zero-based index of button image, -1 if no image for this button.




Der Struktur fehlt also das Member "BYTE bReserved[2] // padding for alignment" und iBitmap ist nicht die SEP-Breite, sondern soll auf -1 gesetzt werden.

Denke, dass der Umstieg auf die MFC dadurch nicht unbedingt erleichtert wird

Gruss,
Frank.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ VC++ / MFC ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: