Page 3 sur 4

Publié : jeu. 03/nov./2005 18:16
par Anonyme2
J'ai corrigé un nouveau bug avec une commande (SetPopupMenuColor() lorsque l'on passe 5 paramètres, on a un magnifique stack overflow :jesors: )

Je met la nouvelle version (3.20) ce soir si j'ai le temps mais je ne pense pas sinon demain

Avez-vous fait des tests sous Millenium ? Moi je ne l'ai pas et comme les bug corrigés sous Win98 ne sont dus qu'à des fonctionnements différents des API Windows (sauf 1) je me demande si ça fonctionne sous Millenium, Win 2000 (ça fonctionne sous Win2000 professionnele NT, j'ai testé), j'ai limité la correction de la barre de menu à Win98, c'est le seul problème qui pourrait persister je pense.

Pouvez-vous aussi tester sous différentes versions NT

Je vais travailler sur la version 4.00 pour
- redimensionner la barre de Menu
- peut-être ajouter la possiblilité de mettre une image à côté de chaque élément de la barre de Menu
- Prendre en compte le raccourci clavier pour la lettre sélectionnée de l'élément du Menu

Si vous avez des idées d'améliorations, vous pouvez proposer , nouvelles commandes, modification de commandes etc

Publié : jeu. 03/nov./2005 19:17
par nico
Ce qui était vrai pour Win98, l'est aussi pour NT (survol de la barre de menu) mais bon faut savoir que sur NT qu'il n'y a pas de réaction au survol de la barre de menu donc même si tu ne le traites pas ce n'est pas choquant puisque c'est son état normal!

Sinon j'ai vu justement la correction apportée pour le survol de la barre de menu sur win98 et il se peut que dans certain cas un item soit dans son état survolé alors que le curseur se trouve sur une autre fenêtre. Car on ne peut pas être sûr qu'un évènement sera envoyé à la fenêtre lorsque le curseur quitte la barre de menu comme dans le cas de deux fenêtre l'une au dessus de l'autre.

Publié : jeu. 03/nov./2005 20:12
par Anonyme2
J'ai du ruser avec Win98 pour y arriver

Je tiens une variable globale qui représente l'état survolé ou non de l'élément et je teste cette variable dans la callback car je force l'état de l'élément avec l'API HiliteMenuItem et si je suis en survol, j'utilise les valeurs survolées sinon celles de sélection

Il y a peut-être des cas ou la variable n'a pas la bonne valeur, si tu as un code de test, je prend

Sous win98, l'événement #WM_MENUSELECT est généré chaque fois que l'on passe sur un élément de la barre (ou du menu) mais pas sous XP pour la barre de menu

Il faut que j'intercepte les événements #WM_MOUSEMOVE, #WM_MENUSELECT et #WM_NCMOUSEMOVE pour y arriver

Je force cette variable chaque fois que je cré un menu

Voici la partie du code que j'utilise dans la callback, la liste MenuIdentifiant() est la liste des menu (handle, fenêtre) pour chaque menu créé


Code : Tout sélectionner

                  ;- #WM_MOUSEMOVE
            Case #WM_MOUSEMOVE
                  If OSVersion() = #PB_OS_Windows_98
                        hMenu = GetMenu_(hWnd)
                        If hMenu
                              ForEach MenuIdentifiant()
                                    If MenuIdentifiant()\IdDynamiqueCourant = hMenu ; c'est le bon menu
                                          Nb_Items = GetMenuItemCount_(hMenu) - 1
                                          For uItem = 0 To Nb_Items
                                                HiliteMenuItem_(hwnd, hmenu, uItem, #MF_UNHILITE | #MF_BYPOSITION)
                                          Next uItem
                                          Break
                                    EndIf
                              Next
                        EndIf
                  EndIf
                  
                  ;- #WM_MENUSELECT
            Case #WM_MENUSELECT
                  ; uItem = (UINT) LOWORD(wParam);   // menu item or submenu index
                  ; fuFlags = (UINT) HIWORD(wParam); // menu flags
                  ; hmenu = (HMENU) lParam;          // handle of menu clicked
                  ; on regarde si c'est un menutitle
                  If OSVersion() = #PB_OS_Windows_98
                        If Lparam = GetMenu_(hWnd) ; c'est un menutitle
                              ForEach MenuIdentifiant()
                                    If MenuIdentifiant()\IdDynamiqueCourant = Lparam ; c'est le bon menu
                                          ; 33168 = #MF_MOUSESELECT|#MF_OWNERDRAW|#MF_HILITE|#MF_POPUP
                                          wParam = (wParam >> 16) & $0000FFFF
                                          If wParam = #MF_MOUSESELECT | #MF_OWNERDRAW | #MF_HILITE | #MF_POPUP ; c'est le cas sélectionné
                                                If SurvolMenuTitle_Win98 = #True
                                                      SurvolMenuTitle_Win98 = #False
                                                      DrawMenuBar_(hWnd)
                                                EndIf
                                          ElseIf wParam = #MF_OWNERDRAW | #MF_HILITE | #MF_POPUP ; c'est le cas survolé
                                                ; 400 = #MF_OWNERDRAW|#MF_HILITE|#MF_POPUP
                                                If SurvolMenuTitle_Win98 = #False
                                                      SurvolMenuTitle_Win98 = #True
                                                      DrawMenuBar_(hWnd)
                                                EndIf
                                          EndIf
                                          Break
                                    EndIf
                              Next
                        EndIf
                  EndIf
                  
                  ;- #WM_NCMOUSEMOVE
            Case #WM_NCMOUSEMOVE
                  If OSVersion() = #PB_OS_Windows_98
                        hMenu = GetMenu_(hWnd)
                        If hMenu
                              UpperLeft.POINT\x = PeekW( @lParam)
                              UpperLeft.POINT\y = PeekW( @lParam + 2)
                              ForEach MenuIdentifiant()
                                    If MenuIdentifiant()\IdDynamiqueCourant = hMenu ; c'est le bon menu
                                          Nb_Items = GetMenuItemCount_(hMenu) - 1
                                          Element_survoler = -1
                                          For uItem = 0 To Nb_Items
                                                GetMenuItemRect_(hWnd, hMenu, uItem, rc.RECT)
                                                If UpperLeft.POINT\x >= rc\left And UpperLeft.POINT\x <= rc\right
                                                      If UpperLeft.POINT\y >= rc\Top And UpperLeft.POINT\y <= rc\bottom
                                                            Element_survoler = uItem
                                                            Break
                                                      EndIf
                                                EndIf
                                          Next
                                          If Element_survoler > - 1
                                                For uItem = 0 To Nb_Items
                                                      If Element_survoler = uItem
                                                            HiliteMenuItem_(hwnd, hmenu, 	uItem, #MF_HILITE | #MF_BYPOSITION)
                                                      Else
                                                            HiliteMenuItem_(hwnd, hmenu, 	uItem, #MF_UNHILITE | #MF_BYPOSITION)
                                                      EndIf
                                                Next uItem
                                          Else
                                                For uItem = 0 To Nb_Items
                                                      HiliteMenuItem_(hwnd, hmenu, 	uItem, #MF_UNHILITE | #MF_BYPOSITION)
                                                Next uItem
                                          EndIf
                                          Break
                                    EndIf
                              Next
                        EndIf
                  EndIf

Publié : ven. 04/nov./2005 17:33
par Anonyme2
Voici la version 3.20

- Correction du bug de la commande SetPopupMenuColor().
- Simplifications importantes du code :

Les commandes suivantes partagent le même code et se situent donc à la même adresse.
  • - DisableMenuItemColor() et DisablePopupMenuItemColor()
    - GetMenuTextColor() et GetPopupMenuTextColor()
    - SetMenuTextColor() et SetPopupMenuTextColor()
    - SetMenuItemStateColor() et SetPopupMenuItemStateColor()
    - SetMenuFontColor et SetPopupMenuFontColor
    - SetMenuItemFontColor() et SetPopupMenuItemFontColor()
    - SetMenuImageColor() et SetPopupMenuImageColor()
    - SetMenuColor() et SetPopupMenuColor()
    - SetMenuItemColor() et SetPopupMenuItemColor()
La doc a été mise à jour

Le fichier zip est ici

Il contient 5 fichiers, seul la lib et le chm ont changé par rapport à la 3.10


MoreMenu --> la librairie à installer dans le dossier PureBasic\Purelibraries\userlibraries

MoreMenu.res --> le résident à mettre dans le dossier PureBasic\residents

MoreMenu.chm --> le fichier d'aide à mettre dans le dossier PureBasic\Help

Exemple Menu Couleur.pb --> fichier d'exemple
Exemple Multi_PopupColor.pb --> fichier d'exemple

Publié : ven. 04/nov./2005 18:03
par nico
Comme je n'avais pas encore codé le survol pour window98, je suis parti de ton code, au final j'ai un code plus simple je t'envoie ça en MP.

Publié : ven. 04/nov./2005 18:19
par Anonyme2
Merci Nico,

je vais regarder :D

Publié : ven. 04/nov./2005 18:53
par Backup
J'ai corrigé un nouveau bug avec une commande (SetPopupMenuColor() lorsque l'on passe 5 paramètres, on a un magnifique stack overflow
Ace propos El Choni avait balancé un code sur le forum Anglais
pour augmenter la taille de la pile du purebasic !!

le voici


Hi,
Try this To change stack size:

; ********************************************
OldStack.l
StackSize = 256000
NewStack = AllocateMemory (StackSize)+StackSize
MOV OldStack, esp
MOV esp, NewStack
; Program code
MOV esp, OldStack
FreeMemory (NewStack-StackSize)

; ****************************************



Tested with very few code in the middle, seems to work.

EDIT: yes, your code works with StackSize set to 2560000:

OldStack.l
StackSize = 2560000
NewStack = AllocateMemory (StackSize)+StackSize
MOV OldStack, esp
MOV esp, NewStack


Structure TestStructure
  StringNummer.s
EndStructure
NewList EineListe.TestStructure()

Debug " Erstelle... "
For t=100000 To 119999
   AddElement (EineListe())
  EineListe()\StringNummer= Str (t)
Next

Debug " Start... "
StartTime = ElapsedMilliseconds ()
SortStructuredList (EineListe(),2,OffsetOf(TestStructure\StringNummer), #PB_Sort_String )
Debug " ende "
MessageRequester("",Str(( ElapsedMilliseconds ()-StartTime)/1000))

MOV esp, OldStack
FreeMemory (NewStack-StackSize)

voir ce lien
http://forums.purebasic.com/english/vie ... 26&start=9

Publié : ven. 04/nov./2005 19:15
par Anonyme2
Merci Dobro :D :D :D :D :D :D

je t'explique

J'utilise une procédure pour la transparence des images qui récupère les infos de l'image en faisant une copie puis j'applique la couleur aux pixels voulus.

J'ai créé une variable locale sur la pile de 1 ko pour la copie de mon image - image 16 x 16 x 4 (ça évite l'appel d'une API qui peut échouer) et je me suis demandé dans une grosse application si on pouvait avoir un crash de la pile (comme par exemple lors d'un appel récursif trop important ou mal maitrisé :mrgreen: )

Je vais tester le code de El_Choni

Publié : ven. 04/nov./2005 19:55
par nico
Je te confirme ce que je t'ai dit; je viens de refaire des tests sur win98; un item restera dans son état survolé dans ces deux cas de figures:

- une fenêtre au dessus de la barre de menu, le curseur passant de la barre de menu à une nouvelle fenêtre, tu n'auras pas de message pour actualiser.

-un passage du curseur trop rapide du premier item vers l'extérieur, le message attendu n'est pas transmis dans ce cas!


Comme je te l'ai expliqué, c'est tout à fait normal ce comportement d'où la solution d'utiliser un scan de la position de la souris où alors setcapture!

Je t'aurais bien montré ça en photos, mais lors de la copie d'écran le curseur n'est pas apparent. :lol:

Mais bon si tu fais des tests toi-même tu pourras vérifier!

Publié : ven. 04/nov./2005 20:24
par Anonyme2
Merci,

je vais regarder ça

Publié : sam. 05/nov./2005 7:57
par Jacobus
Nickel ta Lib, fonctionne très bien.

J'ai remarqué que deux fonctions sont identiques
SetPopupMenuColor() et SetMenuColor()
D'ailleurs tu utilises la seconde dans ton exemple de PopUp
L'une ou l'autre c'est pareil, c'est voulu?

Publié : sam. 05/nov./2005 9:12
par Anonyme2
Jacobus a écrit :Nickel ta Lib, fonctionne très bien.

J'ai remarqué que deux fonctions sont identiques
SetPopupMenuColor() et SetMenuColor()
D'ailleurs tu utilises la seconde dans ton exemple de PopUp
L'une ou l'autre c'est pareil, c'est voulu?
Au départ j'ai voulu différencier les commandes propres au menu et popupmenu

Puis, en fin de compte , certaines commandes sont identiques ou s'il elles ne l'étaient pas, j'ai fait en sorte qu'elles le soient

Si on utilise Setmenucolor et setpopupmenucolor ancienne version dans un même programme, on a 2 routines qui se retrouvent dans l'exe alors qu'elles sont identiques

J'ai modifié les fichiers asm pour n'avoir plus qu'une seule routine pour les 2 commandes, j'ai laissé la possibilité d'avoir 2 noms de commandes pour la même routine

C'est valable pour les commande suivantes (celles qui sont sur la même ligne)
  • - DisableMenuItemColor() et DisablePopupMenuItemColor()
    - GetMenuTextColor() et GetPopupMenuTextColor()
    - SetMenuTextColor() et SetPopupMenuTextColor()
    - SetMenuItemStateColor() et SetPopupMenuItemStateColor()
    - SetMenuFontColor et SetPopupMenuFontColor
    - SetMenuItemFontColor() et SetPopupMenuItemFontColor()
    - SetMenuImageColor() et SetPopupMenuImageColor()
    - SetMenuColor() et SetPopupMenuColor()
    - SetMenuItemColor() et SetPopupMenuItemColor()
encore 2 problèmes, la menubar sous Win98 et les polices qui ne sont pas interpretées en mode gras, italiques etc lorsque l'on ne défini pas de police pour l'élément (utilisation de la police système). Je pense avoir résolu le 2ème, celà m'a pris pas mal de temps

Publié : sam. 05/nov./2005 19:46
par Jacobus
Denis, j'ai un bean's avec MoreMenu 3.20 qui ne se produisait pas avant.
Dans ma boucle, pour appeler une fenêtre secondaire, je ferme la fenêtre principale par un CloseWindow() et à la fermeture de ma fenêtre secondaire je relance ma fenêtre principale (qui se trouve dans une procédure) en appelant à nouveau cette procédure. Désormais, le Menu disparaît totalement et pas moyen de le récupérer alors que le PopUpMenu (de la systrayicone) lui est toujours actif. Rien au debugger.

Je vais faire d'autre tests et un code d'exemple pour essayer d'y voir clair et je te tiens au courant. Cela ne se produisait pas avec tes précédentes versions. Ceci sous Win Xp home sp2.

Voilà un code pour test:
A moins que cela ne vienne de moi et de mon code. Si quelqu'un y voit une erreur, qu'il la signale, ça évitera à Denis de chercher pour rien, merci.


;-CONSTANTES
Enumeration
   #WinPB = 0
   #SysTrayIcon
   #win_prefs
   #btn_Quit_Prefs
  ;-Constantes Menu
   #Menu
   #MenuFichier
   #_1
   #MenuBarColor_1
   #_2
   #MenuBarColor_2
   #_3
  ;-Constantes PopUpMenu
   #PopUp
   #_28
   #_29
   #_30
   #PopUpMenuBar_1
  ;-constantes gadgets
   #btn_prefs
  
EndEnumeration
 
Procedure Prefs_User()
   If OpenWindow( #win_prefs ,0,0,500,460, #PB_Window_SystemMenu | #PB_Window_WindowCentered | #PB_Window_TitleBar , " Préférences ") And CreateGadgetList (WindowID( #win_prefs ))
    
     ButtonGadget ( #btn_Quit_Prefs , 20,20,80,20," Quitter ")
   Endif
    Repeat
      EventID = WaitWindowEvent ()
       If EventID = #PB_EventGadget
         Select EventGadgetID ()
          
           Case #btn_Quit_Prefs : Quit = 1
            
         EndSelect
       Endif
     Until EventID = #PB_EventCloseWindow Or Quit = 1
     CloseWindow ( #win_prefs )
   EndProcedure
  
   Procedure GetIcone(WinHandle)
    hInstance = GetWindowLong_(WinHandle, #GWL_HINSTANCE )
    app.s = Space (255)
    GetModuleFileName_(0,@app,255)
     ProcedureReturn ExtractIcon_(hInstance, app, 0)
   EndProcedure
      
Global VarMT.ItemParams
Global Var.ItemParams

Procedure WinPB()
   ExamineDesktops ()
  Largeur$ = Str( DesktopWidth (0))
  Hauteur$ = Str( DesktopHeight (0))
   If Val (Largeur$)>800 And Val (Hauteur$)>600
    FlagWin = #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget | #PB_Window_SizeGadget | #PB_Window_TitleBar | #PB_Window_MaximizeGadget
   Else
    FlagWin = #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_SizeGadget | #PB_Window_TitleBar | #PB_Window_MaximizeGadget
   Endif
  
   If OpenWindow( #WinPB ,0,0,790,550,FlagWin," MoreMenu test ") And CreateGadgetList (WindowID( #WinPB ))
    x = WindowWidth ()
    y = WindowHeight ()
    hIconSysTray = GetIcone( #WinPB )
     AddSysTrayIcon ( #SysTrayIcon ,WindowID( #WinPB ),hIconSysTray)
    SysTrayIconToolTip( #SysTrayIcon ," PureBasic DirAndTools ")
    
    ;-Menu principal
     If CreateMenuColor( #Menu , WindowID())
      VarMT\Text = " Fichier "
      VarMT\TextColor = #Black
      VarMT\TextAreaBkGndColor = #White
      VarMT\SelectedTextColor = #White
      VarMT\SelectedBkGndColor = RGB ($9D,$9D,$FF)
      VarMT\SelectedFrameColor = RGB ($0,$0,$A0)
      VarMT\MouseOverMenuTitleTextColor = #Black
      VarMT\MouseOverMenuTitleBkGndColor = RGB(191, 210, 245)
      VarMT\MouseOverMenuTitleFrameColor = RGB(49, 106, 197)
      MenuTitleColor( #MenuFichier , VarMT)
      
      Var\Text = " Ouvrir "
      Var\TextColor = #Black
      Var\IconAreaBkGndColor = RGB ($CE,$DB,$DB)
      Var\TextAreaBkGndColor = #White
      Var\SelectedTextColor = #Black
      Var\SelectedBkGndColor = RGB (191, 210, 245)
      Var\SelectedFrameColor = RGB (49, 106, 197)
      MenuItemColor( #_1 , Var) : SetMenuItemStateColor( #_1 , 1)
      
      Var\MenuBarColor = 255
      MenuBarColor( #MenuBarColor_1 , Var)
      
      Var\Text = " Quitter "
      MenuItemColor( #_2 , Var)
      Var\MenuBarColor = 255
      MenuBarColor( #MenuBarColor_2 , Var)
      Var\Text = " Préférences "
      MenuItemColor( #_3 , Var)
     Endif
    
    ;-PopupMenu Systray
     If CreatePopupMenuColor( #PopUp )
      Var\Text = " Fenêtre principale "
      Var\TextColor = #Blue
      Var\IconAreaBkGndColor = $E3F0D6
      Var\TextAreaBkGndColor = #White
      Var\SelectedTextColor = 255
      Var\SelectedBkGndColor = RGB (191, 210, 241)
      Var\SelectedFrameColor = RGB (49, 106, 197)
      PopupMenuItemColor( #_28 ,Var)
      
      Var\Text = " Fermer "
      PopupMenuItemColor( #_29 ,Var)
      PopupMenuBarColor( #PopUpMenuBar_1 ,Var)
      Var\Text =" Quitter "
      PopupMenuItemColor( #_30 ,Var)
     Endif
    
     ButtonGadget ( #btn_prefs , 20,20,80,20," Preferences ")
    
   Endif
EndProcedure
    
  ;-PROGRAMME
WinPB()
Repeat
  Event = WaitWindowEvent ()
  
  ;-Systray
   If Event = #PB_Event_SysTray
     Select EventType ()
       Case #PB_EventType_RightClick
        DisplayPopupMenuColor( #PopUp , WindowID( #WinPB ))
     EndSelect
   Endif
  
   If Event = #PB_EventGadget
     Select EventGadgetID ()
      
       Case #btn_prefs
         CloseWindow ( #WinPB )
           RemoveSysTrayIcon ( #SysTrayIcon )
           Prefs_User()
          WinPB()
          
       EndSelect
     Endif
    ;-fonctions Menu et PopUp
     Select Event
       Case #PB_EventMenu
         Select Event MenuID ()
          
           Case #_2 :Quit = #True
            
           Case #_3 : CloseWindow ( #WinPB )
             RemoveSysTrayIcon ( #SysTrayIcon )
            Prefs_User()
            WinPB()
            
           Case #_30 :Quit = #True
             
         EndSelect
        ;-FIN
       Case #PB_Event_CloseWindow : HideWindow( #WinPB , 1)
        
     EndSelect
   Until Quit
  End
        
        

Publié : dim. 06/nov./2005 10:34
par Anonyme2
Voici la version 3.30

- j'ai corrigé le bug.
Je pense avoir trouvé un bug de la commande Purebasic DeleteElement() lorsque l'on utilise le 2ème paramètre. je vais essayer de faire un exemple et poster dans la section bug

La doc a été mise à jour

Il contient les 5 mêmes fichiers, seul la lib et le chm ont changé par rapport à la 3.20

Le fichier zip est ici

Publié : dim. 06/nov./2005 11:07
par Droopy
Sympa ta lib, juste un truc, pourquoi n'utilises tu pas Library Installer 2, de Num3 http://io-soft.planetaclix.pt

Cela simplifie grandement l'installation des libs :wink: