evènements et CreateWindowEx_()

Programmation d'applications complexes
Oliv
Messages : 2117
Inscription : mer. 21/janv./2004 18:39

evènements et CreateWindowEx_()

Message par Oliv »

Comment récupérer les évènements d'une fenêre créée avec CreateWindowEx quand on a utilisée une autre fenêtre entre deux ? Car UseWindow() ne fonctionne pas avec un Handle. J'ai essayé GetMessage_() mais je n'ai pas bien compris comment ça fonctionne :(
Merci
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Message par nico »

Salut Oliv,

Tiens, j'ai récupéré cela sur Purearea:

Code : Tout sélectionner

Procedure WindowCallback(Window, Message, wParam, lParam) 
  Select Message 
    Case #WM_CLOSE 
      If MessageBox_(Window, "Wirklich beenden?", "EXIT", #MB_YESNO) = #IDYES 
        DestroyWindow_(Window) 
      Else 
        Result  = 0 
      EndIf 
    Case #WM_DESTROY 
      PostQuitMessage_(0) 
      Result  = 0 
    Default 
      Result  = DefWindowProc_(Window, Message, wParam, lParam) 
  EndSelect 
  ProcedureReturn Result 
EndProcedure 

#Style  = #WS_VISIBLE | #WS_BORDER | #WS_SYSMENU 
#StyleEx  = #WS_EX_TOOLWINDOW ;| #WS_EX_OVERLAPPEDWINDOW 

WindowClass.s  = "MeinFenster" 
wc.WNDCLASSEX 
wc\cbSize  = SizeOf(WNDCLASSEX) 
wc\lpfnWndProc  = @WindowCallback() 
wc\hCursor  = LoadCursor_(0, #IDC_CROSS); #IDC_ARROW   = Arrow 
; #IDC_SIZEALL = Size Arrow 
; #IDC_CROSS   = Cross 
wc\hbrBackground  = #COLOR_WINDOW + 1;CreateSolidBrush_(RGB($8F,$8F,$8F)) 
wc\lpszClassName  = @WindowClass 
RegisterClassEx_(@wc) 

hWndMain  = CreateWindowEx_(#StyleEx, WindowClass, "Test-Window", #Style, 10, 10, 200, 200, 0, 0, 0, 0) 
CreateWindowEx_(0, "Static", "", #WS_CHILD | #WS_VISIBLE | $12, 9, 9, 102, 22, hWndMain, 0, 0, 0) 
CreateWindowEx_(0, "Button", "Button 1", #WS_CHILD | #WS_VISIBLE, 10, 10, 100, 20, hWndMain, 0, 0, 0) 

ShowWindow_(hWndMain,  #SW_SHOWDEFAULT) 
UpdateWindow_(hWndMain); 

While GetMessage_(msg.MSG, #NULL, 0, 0 ) 
  TranslateMessage_(msg) 
  DispatchMessage_(msg) 
Wend
; ExecutableFormat=Windows
; EOF
Oliv
Messages : 2117
Inscription : mer. 21/janv./2004 18:39

Message par Oliv »

Oui j'ai vu merci mais je ne peux pas utiliser une CallBack() :( car je suis dans une DLL(ou j'ai pas compris comment faire). En fait, je cré une fenêtre avec CreatewindowEx_() dans une procédure de la DLL appelée par le programme, le prog fait ses petites affaires, puis apelle une autre procédure de la DLL. Dans cette procédure, je voudrais regarder les évènements des gadgets mais je ne sais pas comment faire :(
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Message par nico »

Si j'ai bien compris:

-tu lances une fenêtre qui va créer une deuxième fenêtre en appelant une Dll et cette deuxième fenêtre doit te lister les évènements de la première, c'est bien ça?

Question, pourquoi utiliser CreateWindowEx et pas les fonctions de Pure?, et pourquoi utiliser une Dll (Je sais , tu attends plutôt des réponses mais c'est pour mieux t'aider! :) )

Pour une première réponse, je dirais qu'il faut sous-classer la fenêtre...
Oliv
Messages : 2117
Inscription : mer. 21/janv./2004 18:39

Message par Oliv »

Tu as tout as fait raison, la réponse aux pourquoi est 'pourquoi pas ?" comme dirai Dobro :P . Plus sérieusement, je me suis mal expliqué, pardon. C'est pour SoundEditor, il y a une fenêtre générale pour les filtres, qui fait appel à la procédure d'un filtre, cette procédure (si le filtre en a besoin) cré des gadgets sur la première fenêtre. La seule manière trouvée pour ça est de faire

Code : Tout sélectionner

hWnd = CreateWindowEx_(0,"Static","ownwindow",#WS_CHILD | #WS_VISIBLE | $12,0,0,270,90,hWndMain,0,0,0)
où hWndMain est le handle de la première fenêtre. Ensuite SoundEditor reprend la main et traite ses propres gadgets et puis à la DLL de faire de même. Mais là, blocage : comment récupérer les évènements faits dans la fenêtre crée par CreateWindowEx_() (Enfin, ce n'est pas le même identifiant en tant que fenêtre mais par contre au niveau graphisue c'est la même). Voilà, j'espère avoir été clair, merci de ton aide.
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Message par nico »

Pour la CallBack dans une Dll, voilà ce que ça donne, pas de problème chez moi:

Fichier: dll_oliv (compiler et faire une Dll)

Code : Tout sélectionner

Procedure WindowCallback(Window, message, wParam, lParam) 
  Select message 
    Case #WM_COMMAND 
      Select wParam&$FFFF
        Case 10
        MessageBox_(Window, "Info", "Le bouton à été clické",0)
    EndSelect
    
    Case #WM_CLOSE 
      If MessageBox_(Window, "Quitter?", "EXIT", #MB_YESNO) = #IDYES 
        DestroyWindow_(Window) 
      Else 
        result  = 0 
      EndIf
      
    Case #WM_DESTROY 
      PostQuitMessage_(0) 
      result  = 0 
      
    Default 
      result  = DefWindowProc_(Window, message, wParam, lParam) 
  EndSelect 
  ProcedureReturn result 
EndProcedure 

ProcedureDLL Creer_Fenetre()
  #Style  = #WS_VISIBLE | #WS_BORDER | #WS_SYSMENU 
  #StyleEx  = 0
  
  WindowClass.s  = "MaFenetre" 
  wc.WNDCLASSEX 
  wc\cbSize  = SizeOf(WNDCLASSEX) 
  wc\lpfnWndProc  = @WindowCallback() 
  wc\hCursor  = LoadCursor_(0, #IDC_ARROW)
  wc\hbrBackground  = #COLOR_WINDOW + 1;CreateSolidBrush_(RGB($8F,$8F,$8F)) 
  wc\lpszClassName  = @WindowClass 
  RegisterClassEx_(@wc) 
  
  hWndMain  = CreateWindowEx_(#StyleEx, WindowClass, "Test-Window", #Style, 300, 300, 200, 200, 0, 0, 0, 0) 
  CreateWindowEx_(0, "Button", "Button 1", #WS_CHILD | #WS_VISIBLE, 10, 10, 100, 20, hWndMain, 10, 0, 0) 
  
  ShowWindow_(hWndMain,  #SW_SHOWDEFAULT) 
  UpdateWindow_(hWndMain); 
  
  While GetMessage_(msg.MSG, #Null, 0, 0 ) 
    TranslateMessage_(msg) 
    DispatchMessage_(msg) 
  Wend 
EndProcedure

Programme de Test:

Code : Tout sélectionner

#Librairie=0

If OpenWindow(0,200,200,400,400,#PB_Window_SystemMenu|#PB_Window_ScreenCentered,"Pure Basic")
  If CreateGadgetList(WindowID(0)) 
    ButtonGadget(0, 10, 10, 200, 20, "Créer une fenêtre")
  EndIf
   
  Repeat
    EventID.l=WaitWindowEvent()
    Select EventID
      Case #PB_EventGadget
        Select EventGadgetID()
          Case 0
            If OpenLibrary(#Librairie, "dll_oliv.dll")
              Debug "1"
              CallFunction(#Librairie, "Creer_Fenetre")
              CloseLibrary(#Librairie) 
            EndIf 
        EndSelect
        
      Case #WM_CLOSE
        Quit=1
    EndSelect
    
  Until Quit=1
EndIf 
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Message par nico »

Ca marche pour toi, c'est ce que tu cherchais à faire!

:)
Oliv
Messages : 2117
Inscription : mer. 21/janv./2004 18:39

Message par Oliv »

Oui merci :D
Je vais voir ça ce soir
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Message par nico »

Cela fonctionne de la même façon avec une fenêtre créée avec Pure sans CallBack!
Oliv
Messages : 2117
Inscription : mer. 21/janv./2004 18:39

Message par Oliv »

En fait, voilà ce que je souhaiterai faire, mais je n'arrive pas à détecter le boutton : (la DLL s'appelle a.dll)
Code de la DLL

Code : Tout sélectionner

Procedure WindowCallback(Window, message, wParam, lParam) 
  Select message 
    Case #WM_COMMAND 
      Select wParam&$FFFF 
        Case 10 
        MessageBox_(Window, "Info", "Le bouton à été clické",0) 
    EndSelect 
    
    Case #WM_CLOSE 
      If MessageBox_(Window, "Quitter?", "EXIT", #MB_YESNO) = #IDYES 
        DestroyWindow_(Window) 
      Else 
        result  = 0 
      EndIf 
      
    Case #WM_DESTROY 
      PostQuitMessage_(0) 
      result  = 0 
      
    Default 
      result  = DefWindowProc_(Window, message, wParam, lParam) 
  EndSelect 
  ProcedureReturn result 
EndProcedure 

ProcedureDLL Creer_Fenetre(hwndMain) 
  #Style  = #WS_VISIBLE | #WS_BORDER | #WS_SYSMENU 
  #StyleEx  = 0 
  
  WindowClass.s  = "MaFenetre" 
  wc.WNDCLASSEX 
  wc\cbSize  = SizeOf(WNDCLASSEX) 
  wc\lpfnWndProc  = @WindowCallback() 
  wc\hCursor  = LoadCursor_(0, #IDC_ARROW) 
  wc\hbrBackground  = #COLOR_WINDOW + 1;CreateSolidBrush_(RGB($8F,$8F,$8F)) 
  wc\lpszClassName  = @WindowClass 
  RegisterClassEx_(@wc) 

  hWnd = CreateWindowEx_(0,"Static","ownwindow",#WS_CHILD | #WS_VISIBLE | $12,0,0,270,90,hWndMain,0,0,0)
  CreateGadgetList(hWnd)
    ButtonGadget(10,10,10,100,20,"Button 1")
  
  
  ShowWindow_(hWndMain,  #SW_SHOWDEFAULT) 
  UpdateWindow_(hWndMain); 
  
  While GetMessage_(msg.MSG, #Null, 0, 0 ) 
    TranslateMessage_(msg) 
    DispatchMessage_(msg) 
  Wend 
EndProcedure
Et l'appel :

Code : Tout sélectionner

#Librairie=0 
#Fenetre = 0

If OpenWindow(0,200,200,400,400,#PB_Window_SystemMenu|#PB_Window_ScreenCentered,"Pure Basic") 
  If CreateGadgetList(WindowID(0)) 
    ButtonGadget(0, 10, 10, 200, 20, "Créer une fenêtre") 
  EndIf 
    
  Repeat 
    EventID.l=WaitWindowEvent() 
    Select EventID 
      Case #PB_EventGadget 
        Select EventGadgetID() 
          Case 0 
            If OpenLibrary(#Librairie, "a.dll")
              hWndMain  = OpenWindow(#Fenetre,50,30,500,500,0,"Test")
              CallFunction(#Librairie, "Creer_Fenetre",hWndMain) 
              CloseLibrary(#Librairie) 
            EndIf 
        EndSelect 
        
      Case #WM_CLOSE 
        Quit=1 
    EndSelect 
    
  Until Quit=1 
EndIf 
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Message par nico »

Pourquoi tu ne veux pas que cette ligne soit inclus dans la Dll:

hWndMain = OpenWindow(#Fenetre,50,30,500,500,0,"Test")
Oliv
Messages : 2117
Inscription : mer. 21/janv./2004 18:39

Message par Oliv »

Car c'est SoundEditor qui le fait et cré aussi des gadgets dessus. Si tu as le temps et l'envie, regarde sur SoundEditor avec le filtre brillance et tu comprendras, il y a le haut (une trackbar()) faite par le filtre, et le reste fait par SoundEditor
Oliv
Messages : 2117
Inscription : mer. 21/janv./2004 18:39

Message par Oliv »

J'ai trouvé un "bricolage" qui permet de faire ce que je veux, il ne reste plus qu'a savoir si Zapman va être d'accord. En fait, le programme cré une fenêtre et la dll en cré une au dessus avec #PB_Window_BorderLess donc on en voit pas le "bricolage", mais on pourrait peut-être faire mieux quand même :oops:
La DLL

Code : Tout sélectionner

ProcedureDLL Creer_Fenetre() 
  OpenWindow(0,253,127,150,150,#PB_Window_Borderless,"Test")
  CreateGadgetList(WindowID())
    ButtonGadget(0,0,0,150,150,"Boutton DLL")
    SetWindowPos_(WindowID(), -1, 0, 0, 0, 0, #SWP_NOSIZE | #SWP_NOMOVE) 
EndProcedure

ProcedureDLL Events()
  Select WindowEvent()
    Case #PB_EventGadget 
      Select EventGadgetID() 
        Case 0
          MessageRequester("Click","Le boutton de la DLL vient d'être clické")
      EndSelect
  EndSelect
EndProcedure


ProcedureDLL Fermer_Fenetre()
  CloseWindow(0)
EndProcedure
Et le programme

Code : Tout sélectionner

#Librairie=0 
#Fenetre = 1

If OpenWindow(0,100,100,300,150,#PB_Window_SystemMenu,"Pure Basic") 
  If CreateGadgetList(WindowID(0)) 
     ButtonGadget(0,0,0,150,150,"Boutton programme")
  EndIf
  SetWindowPos_(WindowID(), -2, 0, 0, 0, 0, #SWP_NOSIZE | #SWP_NOMOVE) 
  If OpenLibrary(#Librairie, "a.dll")
    CallFunction(#Librairie, "Creer_Fenetre")
    *Events = IsFunction(#Librairie,"Events")

    Repeat
      EventID.l=WindowEvent() 
      Select EventID 
        Case #PB_EventGadget 
          Select EventGadgetID() 
            Case 0
              MessageRequester("Click","Le boutton du programme vient d'être clické")
          EndSelect 
          
        Case #WM_CLOSE 
          Quit=1 
      EndSelect 
      
      CallFunctionFast(*Events)
      
      Delay(10)
    Until Quit=1
    
    CallFunction(#Librairie,"Fermer_Fenetre")
    CloseLibrary(#Librairie)
  EndIf
  
EndIf
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Message par nico »

Tu te compliques , dans ce cas là tu fais:

Code : Tout sélectionner

ProcedureDLL Creer_Fenetre() 
  OpenWindow(0,253,127,150,150,#PB_Window_Borderless,"Test") 
  CreateGadgetList(WindowID()) 
    ButtonGadget(0,0,0,150,150,"Boutton DLL") 
    SetWindowPos_(WindowID(), -1, 0, 0, 0, 0, #SWP_NOSIZE | #SWP_NOMOVE) 

  Select WindowEvent() 
    Case #PB_EventGadget 
      Select EventGadgetID() 
        Case 0 
          MessageRequester("Click","Le boutton de la DLL vient d'être clické") 
      EndSelect 
  EndSelect 

EndProcedure 


Le programme pourra toujours fermer la fenêtre avec un sendmessage!
Oliv
Messages : 2117
Inscription : mer. 21/janv./2004 18:39

Message par Oliv »

oui pour la fermeture du prog, mais refaire

Code : Tout sélectionner

  OpenWindow(0,253,127,150,150,#PB_Window_Borderless,"Test") 
  CreateGadgetList(WindowID()) 
    ButtonGadget(0,0,0,150,150,"Boutton DLL") 
    SetWindowPos_(WindowID(), -1, 0, 0, 0, 0, #SWP_NOSIZE | #SWP_NOMOVE)
fait perdre du temps pour rien
Répondre