OpenWindow() mit Close & MinimizeGadget aber ohne Maximize ?

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
udg
Beiträge: 560
Registriert: 20.06.2013 23:27

Re: OpenWindow() mit Close & MinimizeGadget aber ohne Maximi

Beitrag von udg »

Leider gibts keine einfache Lösung auf normalem Weg wie Ts Soft schon erwähnte.

Da ich aber auch sehr viel Custom Windows mache ist das für mich ok so :)

Es gibt noch eine andere Shadow Version (die Windows Standard) für Borderless Windows, gefällt mir aber nicht so:

Code: Alles auswählen

EnableExplicit

Enumeration
  #Wnd
  #LineTop
  #Gadget_LineTop
  #LineLeft
  #Gadget_LineLeft
  #LineRight
  #Gadget_LineRight
  #LineBottom
  #Gadget_LineBottom
  #Header
  #INFOTEXT
  #Frame
  #Progressbar
  #TextFooter
  #Escape
  #ESCExit
EndEnumeration
;Define startup effect
#AW_BLEND = $80000

Import ""
   GetProcAddress(hMod, Name.p-ascii)
EndImport

#DWMWA_NCRENDERING_POLICY = 2
#DWMNCRP_ENABLED = 2

Structure Margin
   cxLeftWidth.l
   cxRightWidth.l
   cyTopHeight.l
   cyBottomHeight.l
EndStructure

Procedure DwmSetWindowAttribute(hWnd, attr, attrValue)
   Static hMod
   Static Func
      
   Protected Value.integer\i = attrValue
   
   If Not hMod And Not Func
      hMod = GetModuleHandle_("dwmapi")
      Func = GetProcAddress(hMod, "DwmSetWindowAttribute")
   EndIf
   
   If Func
      ProcedureReturn CallFunctionFast(Func, hWnd, attr, Value, SizeOf(Value))
   EndIf
   
   ProcedureReturn -1
EndProcedure


Procedure DwmExtendFrameIntoClientArea(hWnd, Top, Left, Right, Bottom)
   Static hMod
   Static Func
   
   Protected Margin.Margin   

   Margin\cxLeftWidth = Left   
   Margin\cxRightWidth = Right
   Margin\cyTopHeight = Top
   Margin\cyBottomHeight = Bottom
   
   If Not hMod And Not Func
      hMod = GetModuleHandle_("dwmapi")
      Func = GetProcAddress(hMod, "DwmExtendFrameIntoClientArea")
   EndIf
   
   If Func
      ProcedureReturn CallFunctionFast(Func, hWnd, Margin)
   EndIf   
   
   ProcedureReturn -1
EndProcedure

Define Event, Closing

;{ Declare 1px FRAME AROUND OUR WINDOW
;LineTop
CreateImage(#LineTop,508,1,32,RGB(0, 0, 0))
  StartDrawing(ImageOutput(#LineTop))
  StopDrawing()
;LineLeft
CreateImage(#LineLeft,1,240,32,RGB(0, 0, 0))
  StartDrawing(ImageOutput(#LineLeft))
  StopDrawing()
;LineRight
CreateImage(#LineRight,1,240,32,RGB(0, 0, 0))
  StartDrawing(ImageOutput(#LineRight))
  StopDrawing()
;LineBottom
CreateImage(#LineBottom,508,1,32,RGB(0, 0, 0))
  StartDrawing(ImageOutput(#LineBottom))
  StopDrawing()
;}

; MAIN WINDOW
Procedure OpenWnd()
  Protected Window.i
  Protected Font1, Font2, Font3  
  
  Font1 = LoadFont(#PB_Any, "Segoe UI", 11, #PB_Font_HighQuality)
  Font2 = LoadFont(#PB_Any, "Segoe UI", 10, #PB_Font_HighQuality)
  Font3 = LoadFont(#PB_Any, "Segoe UI", 9, #PB_Font_HighQuality)
 
  Window =  OpenWindow(#Wnd, 510, 311, 510, 240, " ", #PB_Window_BorderLess|#PB_Window_ScreenCentered|#WS_VISIBLE|#PB_Window_Invisible)
     SetWindowColor(#Wnd,RGBA(128, 128, 128, 122))
     ;SET OUR TOOL ALWAYS ON TOP (TOPMOST)
      SetWindowPos_(WindowID(#Wnd),#HWND_TOPMOST,0,0,0,0,#SWP_NOMOVE|#SWP_NOSIZE)
   
    ;HEADER
    TextGadget(#Header, 0, 0, 510, 30, "Frameless Window with NORMAL win7 style SHADOW", #SS_CENTERIMAGE|#SS_CENTER)
     SetGadgetColor(#Header, #PB_Gadget_FrontColor, RGB(255, 255, 255))
     SetGadgetColor(#Header, #PB_Gadget_BackColor, RGB(40, 40, 40))
     SetGadgetFont(#Header, FontID(Font1))
     
    ;INFO TEXT
    TextGadget(#INFOTEXT, 10, 70, 490, 20, "Some text here.", #SS_CENTERIMAGE|#SS_CENTER)
     SetGadgetColor(#INFOTEXT, #PB_Gadget_FrontColor, RGB(40, 40, 40))
     SetGadgetColor(#INFOTEXT, #PB_Gadget_BackColor, RGBA(128, 128, 128, 122))
     SetGadgetFont(#INFOTEXT, FontID(Font2))
     
    ;FRAME PROGRESSBAR
    CreateImage(#Frame, 408, 17,32, RGB(24, 24, 24))
     StartDrawing(ImageOutput(#Frame))
        DrawingMode(#PB_2DDrawing_Outlined)
        Box(0, 0, 408, 17, RGB(92,146,191))
     StopDrawing()
     ImageGadget(#Frame, 49, 120, 408, 17, ImageID(#Frame))
     
     ;PROGRESSBAR
      ProgressBarGadget(#Progressbar,  50, 121, 406,  15, 0, 100)
      ;DEFINE PROGRESSBAR SPEED
      AddWindowTimer(0,123,500)
     
    ;ESC INFOTEXT
    TextGadget(#ESCExit, 163, 90, 180, 18, " ", #SS_CENTERIMAGE|#SS_CENTER)
     SetGadgetColor(#ESCExit, #PB_Gadget_FrontColor, RGB(40,40,40))
     SetGadgetColor(#ESCExit, #PB_Gadget_BackColor, RGBA(128, 128, 128, 122))
     SetGadgetFont(#ESCExit, FontID(Font3))
     
    ;TEXT FOOTER
    TextGadget(#TextFooter, 345, 215, 180, 25, "simple example by inc in 2016")
     SetGadgetColor(#TextFooter, #PB_Gadget_FrontColor, RGB(40,40,40))
     SetGadgetColor(#TextFooter, #PB_Gadget_BackColor, RGBA(128, 128, 128, 122))
     SetGadgetFont(#TextFooter, FontID(Font3))     
     
     ;BLACK FRAME AROUND THE TOOL
        ;LineTop
        ImageGadget(#Gadget_LineTop,1,0,508,1,ImageID(#LineTop))
        ;LineLeft
        ImageGadget(#Gadget_LineLeft,0,0,1,240,ImageID(#LineLeft))
        ;LineRight
        ImageGadget(#Gadget_LineRight,509,0,1,240,ImageID(#LineRight))
        ;LineBottom
        ImageGadget(#Gadget_LineBottom,1,239,508,1,ImageID(#LineBottom))
        
        ;GIVE OUR BORDERLESS WINDOW A NORMAL WINDOWS 7 STYLE SHADOW
        If Window
          DwmSetWindowAttribute(WindowID(#Wnd), #DWMWA_NCRENDERING_POLICY, #DWMNCRP_ENABLED)
          DwmExtendFrameIntoClientArea(WindowID(#Wnd), 1, 1, 1, 1)
        EndIf
        
        
    ;Use Tool start up effect
    AnimateWindow_(WindowID(#Wnd),250,#AW_BLEND)
    HideWindow(#Wnd,#False)
  
EndProcedure

OpenWnd()

Repeat
  Event = WaitWindowEvent()
 
  Select Event
    Case #PB_Event_Gadget
     
  EndSelect
 
  ;DRAG WITH MOUSE
  Select Event
    Case #WM_LBUTTONDOWN
         If WindowMouseX(#Wnd) >= 0 And WindowMouseX(#Wnd) <= 510 And WindowMouseY(#Wnd) >= 0 And WindowMouseY(#Wnd) <= 30
            SendMessage_(WindowID(#Wnd), #WM_NCLBUTTONDOWN, #HTCAPTION, 0)
          EndIf
         
    Case #PB_Event_Timer
         Closing + 1
         SetGadgetState(#Progressbar,Closing)
         SetGadgetText(#ESCExit,"Closing in " + StrF(100-(Closing/1),1) + " Seconds or hit ESC") ; update text display                 
         If Closing = 100
           RemoveWindowTimer(0,123)
           End
         EndIf
  EndSelect

  ;ESC END PROGRAM
  If GetAsyncKeyState_(#VK_ESCAPE)
     End 
  EndIf
ForEver
PB v5.43 LTS + v6.02 LTS | Windows 7 x86 + 11 x64 - Gforce RTX 4090 - AMD Ryzen 9 5900X 12-Core Processor 4.2 GHz - 64,0 GB RAM,
ASUSTEK TUF Gaming X570 Plus
ASUS ROG Thor-1200P Platinum (1200W, Aura Sync, OLED Display, 0dB-Cooling)
1x 1 TByte Samsung MZ-V7S500BW 970 EVO Plus 1 TB NVMe M.2 Internal SSD
1x 2 TByte Samsung MZ-V7S2T0BW 970 EVO Plus 2 TB NVMe M.2 Internal SSD
von BiSONTE! TOP. Kauft Eure Hardware gern bei ihm.
Monitor:
LG 38GL950G-B 95 (38 Zoll) Ultragear Curved 21: 9 UltraWide QHD IPS
Benutzeravatar
Mijikai
Beiträge: 754
Registriert: 25.09.2016 01:42

Re: OpenWindow() mit Close & MinimizeGadget aber ohne Maximi

Beitrag von Mijikai »

Danke für den DWM-Api Tipp, die Api hab ich bisher nur für Overlays missbraucht :)
Werds wohl trotzdem nicht nutzen da es optisch (wie erwähnt) kaum was bringt.

Bild
Benutzeravatar
RSBasic
Admin
Beiträge: 8022
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Re: OpenWindow() mit Close & MinimizeGadget aber ohne Maximi

Beitrag von RSBasic »

Ansonsten gibt es ja auch zwei Buttons, aber nicht Minimize und Close, sondern Help und Close und mit einem Event im Callback kann man den Klick auswerten und das Minimieren simulieren:

Code: Alles auswählen

EnableExplicit

Procedure WindowCallback(hWnd, uMsg, wParam, lParam)
  Protected *HELPINFO.HELPINFO
  
  Select uMsg
    Case #WM_SYSCOMMAND
      Select wParam
        Case #SC_CONTEXTHELP
          SetWindowState(0, #PB_Window_Minimize)
          ProcedureReturn 1
      EndSelect
  EndSelect
  
  ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure

If OpenWindow(0, 0, 0, 500, 400, "Window", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  SetWindowLongPtr_(WindowID(0), #GWL_EXSTYLE, GetWindowLongPtr_(WindowID(0),#GWL_EXSTYLE) | #WS_EX_CONTEXTHELP)
  SendMessage_(WindowID(0), #WM_NCPAINT, 1, 0)
  SetWindowCallback(@WindowCallback())
  
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        End
    EndSelect
  ForEver
EndIf
Der Code ist natürlich noch nicht fertig. Was fehlt, ist eine grafische Modifikation des Help-Buttons. Ich weiß zwar gerade nicht wie, aber vielleicht ist es doch irgendwie möglich, die Grafik dieses Buttons nachträglich auszutauschen.

\\Edit:
Oder man verwendet nur den Close-Button und zeichnen einen eigenen Zusazubutton darauf. Beispielsweise mit diesem Code: http://www.purebasic.fr/english/viewtop ... 12&t=44243
Was man noch machen müsste, ist die originale Buttongrafik aus der themeui.dll (o.ä.) zu laden.
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
Benutzeravatar
udg
Beiträge: 560
Registriert: 20.06.2013 23:27

Re: OpenWindow() mit Close & MinimizeGadget aber ohne Maximi

Beitrag von udg »

Mijikai hat geschrieben: Edit: DropShadow hat keinen Effekt bei Win10!
Hallo, gerade meinen Code noch einmal gegen checken lassen in Windows 10. Funktioniert

Was machst Du anders?

Grüße
PB v5.43 LTS + v6.02 LTS | Windows 7 x86 + 11 x64 - Gforce RTX 4090 - AMD Ryzen 9 5900X 12-Core Processor 4.2 GHz - 64,0 GB RAM,
ASUSTEK TUF Gaming X570 Plus
ASUS ROG Thor-1200P Platinum (1200W, Aura Sync, OLED Display, 0dB-Cooling)
1x 1 TByte Samsung MZ-V7S500BW 970 EVO Plus 1 TB NVMe M.2 Internal SSD
1x 2 TByte Samsung MZ-V7S2T0BW 970 EVO Plus 2 TB NVMe M.2 Internal SSD
von BiSONTE! TOP. Kauft Eure Hardware gern bei ihm.
Monitor:
LG 38GL950G-B 95 (38 Zoll) Ultragear Curved 21: 9 UltraWide QHD IPS
Benutzeravatar
Bisonte
Beiträge: 2430
Registriert: 01.04.2007 20:18

Re: OpenWindow() mit Close & MinimizeGadget aber ohne Maximi

Beitrag von Bisonte »

Mijikai hat geschrieben:Danke @udg
Ich hatte auf eine einfache Windows (OS) Lösung gehofft.
Sobald ich etwas Zeit habe werde ich ein Modul erstellen, die DropShadow Möglichkeit war mir unbekannt.
Edit: DropShadow hat keinen Effekt bei Win10!
Ähm, da möchte ich Dir als Ersteller der DropShadow Prozedure, der selbst Windows 10 am laufen hat, vehement widersprechen.

Man muss bei diesem API Aufruf nur sicherstellen, das das Fenster vorher mit dem #PB_Window_Invisible Flag erstellt wurde !
Dann am Ende das HideWindow() um das Fenster anzeigen zu lassen, und voila, der Schatten ist um das Fenster gepinselt.
PureBasic 6.10 LTS (Windows x86/x64) | Windows10 Pro x64 | Asus TUF X570 Gaming Plus | R9 5900X | 64GB RAM | GeForce RTX 3080 TI iChill X4 | HAF XF Evo | build by vannicom​​
Benutzeravatar
Mijikai
Beiträge: 754
Registriert: 25.09.2016 01:42

Re: OpenWindow() mit Close & MinimizeGadget aber ohne Maximi

Beitrag von Mijikai »

Nachdem ich das Ganze auf 2 verschiedenen Rechnern getestet habe steht fest:

Die besagten Methoden sind von System-Einstellungen abhängig und somit ungeeignet für eine GUI Lösung.
Vorausgesetzt man setzt auf ein immer gleiches Ergebnis.
Zuletzt geändert von Mijikai am 23.07.2017 12:09, insgesamt 1-mal geändert.
Benutzeravatar
RSBasic
Admin
Beiträge: 8022
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Re: OpenWindow() mit Close & MinimizeGadget aber ohne Maximi

Beitrag von RSBasic »

Das im Compiler-Einstellungsfenster eingestellte Icon kannst du mit folgendem Code ermitteln: http://www.rsbasic.de/aktualisierung/wi ... mitteln.pb
Kannst du dein Fenster schon verschieben?
Was noch fehlt:
  • Fensterrahmen
  • Kontextmenü für die Titelleiste
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
Benutzeravatar
Bisonte
Beiträge: 2430
Registriert: 01.04.2007 20:18

Re: OpenWindow() mit Close & MinimizeGadget aber ohne Maximi

Beitrag von Bisonte »

Ohne RSBasic beim helfen bremsen zu wollen... ;)

Das ganze funktioniert (ausser dem Icon aus der exe holen) auch mit nativen PB Befehlen, also Crossplatform ;)
Man braucht dafür auch nur 2 Gadgets. Ein Canvas mit ContainerOption und ein Container (für die eigentliche Oberfläche).
PureBasic 6.10 LTS (Windows x86/x64) | Windows10 Pro x64 | Asus TUF X570 Gaming Plus | R9 5900X | 64GB RAM | GeForce RTX 3080 TI iChill X4 | HAF XF Evo | build by vannicom​​
Antworten