ContainerGadget selber erstellen (per WinAPI)

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
nicolaus
Moderator
Beiträge: 1175
Registriert: 11.09.2004 13:09
Kontaktdaten:

ContainerGadget selber erstellen (per WinAPI)

Beitrag von nicolaus »

Hi

Da ich ich prob beim erstellen eines eigenen ContainerGadgets hatte (per WinAPI) habe ich Danilo mal gefragt ob er mir helfen könnte und was ich falsch mache und er hat mir dann dazu ein gleines beispiel geschrieben was ich euch nicht vorenthalten möchte. Hier nun das beispiel:

Code: Alles auswählen

; 
; by Danilo, 10th December 2004 
; 
;   simple WinAPI container example 
; 
Procedure Container_Callback(hWnd,Msg,wParam,lParam) 
  Select Msg 
    Case #WM_LBUTTONDOWN ; Beispiel fr linken Button Down 
      Beep_(800,100) 
      ProcedureReturn 0 
    Case #WM_RBUTTONDOWN ; Beispiel fr rechten Button Down 
      Beep_(600,50) 
      ProcedureReturn 0 
    Case #WM_DESTROY     ; Hintergrundfarbe loeschen/freigeben 
      DeleteObject_( GetClassLong_(hWnd,#GCL_HBRBACKGROUND) ) 
      Beep_(600,50):Beep_(800,50) ; Telefon ... LOL ;) 
      ProcedureReturn 0 
  EndSelect 
  PB_Callback = GetWindowLong_(hWnd,#GWL_USERDATA) 
  If PB_Callback 
    ProcedureReturn CallWindowProc_(PB_Callback,hWnd,Msg,wParam,lParam) 
  Else 
    ProcedureReturn DefWindowProc_(hWnd,Msg,wParam,lParam) 
  EndIf 
EndProcedure 

Procedure Container(x,y,width,height,parent,backcolor,border) 
  ; 
  ; Container erstellen mit eigener Hintergrundfarbe und Rahmen 
  ; 
  #Borderless = $0000 
  #Flat       = $0001 
  #Raised     = $0002 
  #Single     = $0004 
  #Double     = $0008 
  #Thick      = $0010 

  Static container_count 

  ; Select Border Style 
  If     (border & #Flat) 
    Style   = #WS_BORDER;                   Border = 2; 
  ElseIf (border & #Single) 
    ExStyle = #WS_EX_STATICEDGE;            Border = 2; 
  ElseIf (border & #Raised) 
    Style   = #WS_DLGFRAME;                 Border = 6; 
  ElseIf (border & #Double) 
    ExStyle = #WS_EX_CLIENTEDGE;            Border = 4; 
  ElseIf (border & #Thick) 
    ExStyle = #WS_EX_CLIENTEDGE; 
    Style   = #WS_DLGFRAME;                 Border = 10; 
  EndIf 

  If backcolor = -1 
    backcolor  = GetSysColor_(#COLOR_BTNFACE) 
  EndIf 

  ; Create Window Class 
  window_class$ = "PB_Container_Danilo_"+RSet(Hex(container_count),8,"0") 
  container_count + 1 

  wc.WNDCLASSEX 
  wc\cbSize        = SizeOf(WNDCLASSEX) 
  wc\lpfnWndProc   = @Container_Callback() 
  wc\hInstance     = 0 
  wc\hCursor       = LoadCursor_(0, #IDC_ARROW)  ; #IDC_ARROW   = Arrow 
                                                 ; #IDC_SIZEALL = Size Arrow 
                                                 ; #IDC_CROSS   = Cross 
  wc\hbrBackground = CreateSolidBrush_(backcolor) 
  wc\lpszClassName = @window_class$ 
  If RegisterClassEx_(@wc) 
    hContainer = CreateWindowEx_(ExStyle,window_class$,0,#WS_CHILD|#WS_VISIBLE|Style,x,y,width,height,parent,0,GetModuleHandle_(0),0) 
    If hContainer 
      SetWindowLong_(hContainer,#GWL_USERDATA,GetWindowLong_(WindowID(),#GWL_WNDPROC)) 
      ProcedureReturn hContainer 
    EndIf 
  EndIf 
EndProcedure 


Procedure Message(Msg$) 
  ; 
  ; Display new message 
  ; 
  Static MessageCount 
  MessageCount +1 
  AddGadgetItem(0,-1,RSet(StrU(MessageCount,#LONG),10,"0")+": "+Msg$) 
  SendMessage_(GadgetID(0),#LB_SETTOPINDEX,CountGadgetItems(0)-1,0) 
EndProcedure 


hWnd.l = OpenWindow(0,0,0,490,440,#PB_Window_SystemMenu|#PB_Window_ScreenCentered,"Container") 
  CreateGadgetList(hWnd) 
  ListViewGadget(0,10,330,470,100) ; Message Window 
    AddGadgetItem(0,-1,"Messages:") 
    SetGadgetFont(0,LoadFont(0,"Courier New",10)) 

  hContainer1 = Container( 10, 10,150,150,hWnd,RGB($80,$80,$80),#Borderless) 

  hContainer2 = Container(170, 10,150,150,hWnd,RGB($B0,$B0,$00),#Flat) 
    UseGadgetList(hContainer2) 
    ButtonGadget(2,10,10,100,20,"Btn 1") 

  hContainer3 = Container(330, 10,150,150,hWnd,RGB($80,$80,$80),#Raised) 
    UseGadgetList(hContainer3) 
    ButtonGadget(3,10,10,100,20,"Btn 2") 

  hContainer4 = Container( 10,170,150,150,hWnd,       -1       ,#Single) 
    UseGadgetList(hContainer4) 
    ListViewGadget(4,10,10,128,128) 
      For i = 0 To 99 
        AddGadgetItem(4,-1,"ListView Item"+Str(i)) 
      Next i 

  hContainer5 = Container(170,170,150,150,hWnd,       -1       ,#Double) 
    UseGadgetList(hContainer5) 
    PanelGadget(5,10,10,128,128) 
      For i = 0 To 1 
        AddGadgetItem(5,-1,"Panel "+Str(i)) 
      Next i 

  hContainer6 = Container(330,170,150,150,hWnd,       -1       ,#Thick) 
    UseGadgetList(hContainer6) 
    TreeGadget(6,10,10,128,128) 
      For i = 1 To 20 
        If i%5=0 
          AddGadgetItem(6,-1,"Tree "+Str(i)) 
          OpenTreeGadgetNode(6) 
          For a = 0 To 9 
            AddGadgetItem(6,-1,"SubItem "+Str(a)) 
          Next a 
          CloseTreeGadgetNode(6) 
        Else 
          AddGadgetItem(6,-1,"Tree "+Str(i)) 
        EndIf 
      Next i 

Repeat 
  Select WaitWindowEvent() 
     Case #PB_Event_CloseWindow 
       Break 
     Case #PB_Event_Gadget 
       Select EventGadgetID() 
         Case 2 
           Message("Button 1 geklickt") 
         Case 3 
           Message("Button 2 geklickt") 
         Case 4 
           Message("ListView Item "+Str( GetGadgetState(4) )) 
         Case 5 
           Message("Panel Item "   +Str( GetGadgetState(5) )) 
         Case 6 
           ;If EventType()=#PB_EventType_LeftClick 
             Message("Tree Item "  +Str( GetGadgetState(6) )) 
           ;EndIf 
       EndSelect 
  EndSelect 
ForEver 
; ExecutableFormat=Windows 
; DisableDebugger 
; EOF
@Andre
CodeArchive ???!!!

MfG Nico
Benutzeravatar
Andre
PureBasic Team
Beiträge: 1765
Registriert: 11.09.2004 16:35
Computerausstattung: MacBook Core2Duo mit MacOS 10.6.8
Lenovo Y50 i7 mit Windows 10
Wohnort: Saxony / Deutscheinsiedel
Kontaktdaten:

Beitrag von Andre »

@Nico (Danilo): aber freilich doch :wink:
Bye,
...André
(PureBasicTeam::Docs - PureArea.net | Bestellen:: PureBasic | PureVisionXP)
Benutzeravatar
nicolaus
Moderator
Beiträge: 1175
Registriert: 11.09.2004 13:09
Kontaktdaten:

Beitrag von nicolaus »

Ok nachdem ich im code einen fehler festgestellt hatte das wenn man zuerst eine toolbar und/oder statusbar erstellt und dann den eigenen Container erstellt, das Programm abstürzt habe ich danilo nochmals um rat gefragt und auch selber daran gebastelt.
Ich hatte es dann soweit hin bekommen das es mit ToolBars und Co geht jedoch konnte ich den Containern keine eigene Farbe mehr zuordnen.
Die Rettung ist dann mal wieder von Danilo gekommen (an der stelle nochmals super dank an Danilo!!!!!) und das prob war garnich so einfach zu lösen wie ich an dem nachfolgenden und veränderten code von Danilo gesehen habe.

Also hier nun das verbesserte beispiel von Danilo:

Code: Alles auswählen

;
; simple WinAPI container example
;
;
; by Danilo, 10th December 2004
;
;   * changed by Danilo, 12th December 2004
;
;     - didnt work with PB's CreateToolbar command
;       because PB seems to SubClass the window.
;       Uses the internal PB callback directly now.
;
;
Global PB_Callback_intern

Procedure GetPBCallback()
  ; ermittelt die adresse des internen PB-Callbacks.
  ;
  ; muss einmal aufgerufen werden, direkt nachdem das
  ; 1. fenster erstellt wurde.

; ASM:
  !EXTRN PB_ProcessEvent
  !MOV   dword EAX,PB_ProcessEvent
  ProcedureReturn
; alternativer Weg statt ASM:
;  ProcedureReturn GetClassLong_(WindowID(),#GCL_WNDPROC)
EndProcedure


Procedure Container_Callback(hWnd,Msg,wParam,lParam)
  ;
  ; Callback fuer Container
  ;
  Select Msg
    Case #WM_LBUTTONDOWN ; Beispiel fr linken Button Down
      Beep_(800,100)
      ProcedureReturn 0
    Case #WM_RBUTTONDOWN ; Beispiel fr rechten Button Down
      Beep_(600,50)
      ProcedureReturn 0
    Case #WM_DESTROY     ; Hintergrundfarbe loeschen/freigeben
      DeleteObject_( GetClassLong_(hWnd,#GCL_HBRBACKGROUND) )
      Beep_(600,50):Beep_(800,50) ; Telefon ... LOL ;)
      ProcedureReturn 0
  EndSelect
  If PB_Callback_intern
    ProcedureReturn CallWindowProc_(PB_Callback_intern,hWnd,Msg,wParam,lParam)
  Else
    ProcedureReturn DefWindowProc_(hWnd,Msg,wParam,lParam)
  EndIf
EndProcedure

Procedure Container(x,y,width,height,parent,backcolor,border)
  ;
  ; Container erstellen mit eigener Hintergrundfarbe und Rahmen
  ;
  #Borderless = $0000
  #Flat       = $0001
  #Raised     = $0002
  #Single     = $0004
  #Double     = $0008
  #Thick      = $0010

  Static container_count

  ; Select Border Style
  If     (border & #Flat)
    Style   = #WS_BORDER;                   Border = 2;
  ElseIf (border & #Single)
    ExStyle = #WS_EX_STATICEDGE;            Border = 2;
  ElseIf (border & #Raised)
    Style   = #WS_DLGFRAME;                 Border = 6;
  ElseIf (border & #Double)
    ExStyle = #WS_EX_CLIENTEDGE;            Border = 4;
  ElseIf (border & #Thick)
    ExStyle = #WS_EX_CLIENTEDGE;
    Style   = #WS_DLGFRAME;                 Border = 10;
  EndIf

  If backcolor = -1
    backcolor  = GetSysColor_(#COLOR_BTNFACE)
  EndIf

  ; Window Class erstellen
  window_class$ = "PB_Container_Danilo_"+RSet(Hex(container_count),8,"0")
  container_count + 1

  wc.WNDCLASSEX
  wc\cbSize        = SizeOf(WNDCLASSEX)
  wc\lpfnWndProc   = @Container_Callback()
  wc\hInstance     = 0
  wc\hCursor       = LoadCursor_(0, #IDC_ARROW)  ; #IDC_ARROW   = Arrow
                                                 ; #IDC_SIZEALL = Size Arrow
                                                 ; #IDC_CROSS   = Cross
  wc\hbrBackground = CreateSolidBrush_(backcolor)
  wc\lpszClassName = @window_class$
  If RegisterClassEx_(@wc)
    ProcedureReturn CreateWindowEx_(ExStyle,window_class$,0,#WS_CHILD|#WS_VISIBLE|Style,x,y,width,height,parent,0,GetModuleHandle_(0),0)
  EndIf
EndProcedure


Procedure Message(Msg$)
  ;
  ; Nachricht anzeigen
  ;
  Static MessageCount
  MessageCount +1
  AddGadgetItem(0,-1,RSet(StrU(MessageCount,#LONG),10,"0")+": "+Msg$)
  SendMessage_(GadgetID(0),#LB_SETTOPINDEX,CountGadgetItems(0)-1,0)
EndProcedure


hWnd.l = OpenWindow(0,0,0,490,440,#PB_Window_Invisible|#PB_Window_SystemMenu|#PB_Window_ScreenCentered,"Container")
  ;
  ; internen PB-Callback ermitteln
  ;
  PB_Callback_intern = GetPBCallback()

#USE_ToolbarPro = 0
CompilerIf #USE_ToolbarPro = 0
  ;
  ; Toolbar mit PB erstellen
  ;
  CreateToolBar(0,hWnd)
    ToolBarStandardButton(100,#PB_ToolBarIcon_New)
    ToolBarStandardButton(101,#PB_ToolBarIcon_Open)
    ToolBarStandardButton(102,#PB_ToolBarIcon_Save)
    ToolBarSeparator()
    ToolBarStandardButton(103,#PB_ToolBarIcon_Cut)
    ToolBarStandardButton(104,#PB_ToolBarIcon_Copy)
    ToolBarStandardButton(105,#PB_ToolBarIcon_Paste)
    ToolBarSeparator()
  TBheight = 22
CompilerElse
  ;
  ; Toolbar mit ToolbarPro (PureTools) erstellen
  ;
  CreateTB(0,hWnd,16,16,#TBpro_FLAT|#TBpro_TRANSPARENT)
    SetTBimage(0,0,#TBpro_NORMAL)
    SetTBimage(0,0,#TBpro_Hot)
    SetTBimage(0,0,#TBpro_Disabled)
    AddTBsysIcons()
   
    AddTBbutton(100,#TBpro_FILENEW ,#TBpro_Button)
    AddTBbutton(101,#TBpro_FILEOPEN,#TBpro_Button)
    AddTBbutton(102,#TBpro_FILESAVE,#TBpro_Button)
    AddTBseparator(20)
    AddTBbutton(103,#TBpro_CUT     ,#TBpro_Button)
    AddTBbutton(104,#TBpro_COPY    ,#TBpro_Button)
    AddTBbutton(105,#TBpro_PASTE   ,#TBpro_Button)
    AddTBseparator(20)
  TBheight = TBheight(0)
CompilerEndIf

  ;
  ; Gadgets erstellen
  ;
  CreateGadgetList(hWnd)
  ListViewGadget(0,10,330+TBheight,470,100) ; Message Window
    AddGadgetItem(0,-1,"Messages:")
    SetGadgetFont(0,LoadFont(0,"Courier New",10))

  hContainer1 = Container( 10, 10+TBheight,150,150,hWnd,RGB($80,$80,$80),#Borderless)

  hContainer2 = Container(170, 10+TBheight,150,150,hWnd,RGB($B0,$B0,$00),#Flat)
    UseGadgetList(hContainer2)
    ButtonGadget(2,10,10,100,20,"Btn 1")

  hContainer3 = Container(330, 10+TBheight,150,150,hWnd,RGB($80,$80,$80),#Raised)
    UseGadgetList(hContainer3)
    ButtonGadget(3,10,10,100,20,"Btn 2")

  hContainer4 = Container( 10,170+TBheight,150,150,hWnd,       -1       ,#Single)
    UseGadgetList(hContainer4)
    ListViewGadget(4,10,10,128,128)
      For i = 0 To 99
        AddGadgetItem(4,-1,"ListView Item"+Str(i))
      Next i

  hContainer5 = Container(170,170+TBheight,150,150,hWnd,       -1       ,#Double)
    UseGadgetList(hContainer5)
    PanelGadget(5,10,10,128,128)
      For i = 0 To 1
        AddGadgetItem(5,-1,"Panel "+Str(i))
      Next i

  hContainer6 = Container(330,170+TBheight,150,150,hWnd,       -1       ,#Thick)
    UseGadgetList(hContainer6)
    TreeGadget(6,10,10,128,128)
      For i = 1 To 20
        If i%5=0
          AddGadgetItem(6,-1,"Tree "+Str(i))
          OpenTreeGadgetNode(6)
          For a = 0 To 9
            AddGadgetItem(6,-1,"SubItem "+Str(a))
          Next a
          CloseTreeGadgetNode(6)
        Else
          AddGadgetItem(6,-1,"Tree "+Str(i))
        EndIf
      Next i

  ;
  ; Fenstergroesse anpassen und Fenster anzeigen
  ;
  ResizeWindow(490,440+TBheight)
  HideWindow(0,0)

;
; Hauptschleife zur Nachrichtenverarbeitung
;
Repeat
  Select WaitWindowEvent()
     Case #PB_Event_CloseWindow
       Break
     Case #PB_Event_Gadget
       Select EventGadgetID()
         Case 2
           Message("Button 1 geklickt")
         Case 3
           Message("Button 2 geklickt")
         Case 4
           Message("ListView Item "+Str( GetGadgetState(4) ))
         Case 5
           Message("Panel Item "   +Str( GetGadgetState(5) ))
         Case 6
           ;If EventType()=#PB_EventType_LeftClick
             Message("Tree Item "  +Str( GetGadgetState(6) ))
           ;EndIf
       EndSelect
  EndSelect
ForEver
@Andre
Also bitte das ins CodeArchiv und das erste wegen dem fehler verwerfen :wink:
Benutzeravatar
Andre
PureBasic Team
Beiträge: 1765
Registriert: 11.09.2004 16:35
Computerausstattung: MacBook Core2Duo mit MacOS 10.6.8
Lenovo Y50 i7 mit Windows 10
Wohnort: Saxony / Deutscheinsiedel
Kontaktdaten:

Beitrag von Andre »

@Nicolaus: gebongt :wink:
Bye,
...André
(PureBasicTeam::Docs - PureArea.net | Bestellen:: PureBasic | PureVisionXP)
mipooh
Beiträge: 226
Registriert: 12.12.2004 04:49
Kontaktdaten:

Beitrag von mipooh »

Da ist wohl etwas durcheinandergeraten. Zumindest werden bei mir vom Tree5 an Ausgaben angezeigt, die mit den Tree-Angaben nicht übereinstimmen.

Gruss
Mipooh
FloHimself
Beiträge: 338
Registriert: 05.09.2004 18:47

Beitrag von FloHimself »

Hi,

hat schonmal jemand ein ContainerGadget mit einer WS_CAPTION erstellt? Also ein ContainerGadget mit einer Überschrift wie ein Fenster, aber nicht bewegbar?

Gruß,
Flo
Benutzeravatar
nicolaus
Moderator
Beiträge: 1175
Registriert: 11.09.2004 13:09
Kontaktdaten:

Beitrag von nicolaus »

FloHimself hat geschrieben:Hi,

hat schonmal jemand ein ContainerGadget mit einer WS_CAPTION erstellt? Also ein ContainerGadget mit einer Überschrift wie ein Fenster, aber nicht bewegbar?

Gruß,
Flo
Bei welchem Containergadget willst du das denn machen? bei dem originalen von PB oder bei dem mit der api erstellten?

Gruß Nico
FloHimself
Beiträge: 338
Registriert: 05.09.2004 18:47

Beitrag von FloHimself »

Per WinAPI. Es ist auch kein Problem, bis auf das die Fensterleiste des Containers deaktiviert erscheint, also ausgegraut. Es sind quasi Fenster bei denen das Bewegen per Callback überschrieben wird.
Antworten