[Erledigt]Desktop Hintergrund DC ermitteln

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
Mijikai
Beiträge: 754
Registriert: 25.09.2016 01:42

Re: Desktop Hintergrund DC ermitteln

Beitrag von Mijikai »

Habs auch ohne Erfolg versucht.

Meine GetDesktopHwnd() Variante:

Code: Alles auswählen

Procedure.i GetDesktopHwnd()
  Protected hshell.i
  Protected hview.i
  Protected hworker.i
  hshell = GetShellWindow_()
  If hshell
    SendMessage_(hshell,$052C,$D,#False)
    SendMessage_(hshell,$052C,$D,#True)
    hshell = GetDesktopWindow_()
    Repeat
      hworker = FindWindowEx_(hshell,hworker,"WorkerW",#Null)
      If hworker
        hview = FindWindowEx_(hworker,#Null,"SHELLDLL_DefView",#Null)
        If hview
          ProcedureReturn FindWindowEx_(hview,#Null,"SysListView32",#Null)
        EndIf
      EndIf
    Until hworker = #Null
  EndIf
  ProcedureReturn #Null
EndProcedure
:coderselixir:
ccode_new
Beiträge: 1214
Registriert: 27.11.2016 18:13
Wohnort: Erzgebirge

Re: Desktop Hintergrund DC ermitteln

Beitrag von ccode_new »

Das Ganze scheint unter Windows 10 echt knifflig zu sein.

Mehr als einen Rahmen um die Icons bekomme ich bisher nicht hin:

Code: Alles auswählen

Procedure DrawTransparentImage(DC, Bitmap, x, y, Width, Height, TransparentColor)
  
  ; First, create some DC's. These are our gateways To associated
  ; bitmaps in RAM
  maskDC = CreateCompatibleDC_(DC)
  tempDC = CreateCompatibleDC_(DC)
  
  SourceDC = CreateCompatibleDC_(DC)
  SelectObject_(SourceDC, Bitmap)
  
  
  ; Then, we need the bitmaps. Note that we create a monochrome
  ; bitmap here!
  ; This is a trick we use For creating a mask fast enough.
  hMaskBmp = CreateBitmap_(Width, Height, 1, 1, 0)
  hTempBmp = CreateCompatibleBitmap_(DC, Width, Height)
  
  ; Then we can assign the bitmaps to the DCs
  ;
  hMaskBmp = SelectObject_(maskDC, hMaskBmp)
  hTempBmp = SelectObject_(tempDC, hTempBmp)
  
  ; Now we can create a mask. First, we set the background color
  ; To the transparent color; then we copy the image into the
  ; monochrome bitmap.
  ; When we are done, we reset the background color of the
  ; original source.
  TransparentColor= SetBkColor_(SourceDC, TransparentColor)
  BitBlt_ (maskDC, 0, 0, Width, Height, SourceDC, 0, 0, #SRCCOPY)
  SetBkColor_(SourceDC, TransparentColor)
  
  ; The first we do with the mask is To MergePaint it into the
  ; destination.
  ; This will punch a WHITE hole in the background exactly were
  ; we want the graphics To be painted in.
  BitBlt_ (tempDC, 0, 0, Width, Height, maskDC, 0, 0, #SRCCOPY)
  BitBlt_ (DC, x, y, Width, Height, tempDC, 0, 0, #MERGEPAINT)
  
  ; Now we delete the transparent part of our source image. To do
  ; this, we must invert the mask And MergePaint it into the
  ; source image. The transparent area will now appear as WHITE.
  BitBlt_ (maskDC, 0, 0, Width, Height, maskDC, 0, 0, #NOTSRCCOPY)
  BitBlt_ (tempDC, 0, 0, Width, Height, SourceDC, 0, 0, #SRCCOPY)
  BitBlt_ (tempDC, 0, 0, Width, Height, maskDC, 0, 0, #MERGEPAINT)
  
  ; Both target And source are clean. All we have To do is To And
  ; them together!
  BitBlt_ (DC, x, y, Width, Height, tempDC, 0, 0, #SRCAND)
  
  ; Now all we have To do is To clean up after us And free system
  ; resources..
  DeleteObject_ (hMaskBmp)
  DeleteObject_ (hTempBmp)
  DeleteDC_ (maskDC)
  DeleteDC_ (tempDC)
  DeleteDC_ (SourceDC)
  
EndProcedure

Procedure.i GetDesktopHwnd() ;Modifiziert
  Protected hshell.i
  Protected hview.i
  Protected hworker.i
  Protected hsys.i
  hshell = GetShellWindow_()
  If hshell
    SendMessage_(hshell,$052C,$D,#False)
    SendMessage_(hshell,$052C,$D,#True)
    hshell = GetDesktopWindow_()
    Repeat
      hworker = FindWindowEx_(hshell,hworker,@"WorkerW",#Null) ;Unicode-Pointer (LPCSTR)
      If hworker
        hview = FindWindowEx_(hworker,#Null,@"SHELLDLL_DefView",#Null)
        If hview
          Debug "hier"
          hsys = FindWindowEx_(hview,#Null,@"SysListView32", @"FolderView")
          ProcedureReturn hsys
          ;If hsys
          ;  ProcedureReturn FindWindowEx_(hsys,#Null,@"SysHeader32",#Null)
          ;EndIf
        EndIf
      EndIf
    Until hworker = #Null
  EndIf
  ProcedureReturn #Null
EndProcedure

ExamineDesktops()

Global Frame.rect
Frame\bottom = DesktopHeight(0) * DesktopResolutionY()
Frame\left = 10 ;?
Frame\right = DesktopWidth(0) * DesktopResolutionX()
Frame\top = 10 ;?

Global.i hdc, hw
hw = GetDesktopHwnd()
Debug hw
hdc = GetDCEx_(hw, #Null, $403)
Debug hdc

If CreateImage(0, Frame\right, Frame\bottom, 32)
  StartDrawing(ImageOutput(0))
  Box(0, 0, OutputWidth(), OutputHeight(), RGB(255,0,0))
  StopDrawing()
EndIf

;InvalidateRect_(hdc, @Frame, #True)
DrawTransparentImage(hdc, ImageID(0), 0, 0, ImageWidth(0), ImageHeight(0), RGB(0,0,0))
RedrawWindow_( hw, @Frame, 0, #RDW_NOERASE | #RDW_INVALIDATE | #RDW_UPDATENOW | #RDW_NOCHILDREN)

;RedrawWindow_( GetShellWindow_(), @Frame, #Null, #RDW_ERASE | #RDW_UPDATENOW )
Ich bin mir noch nicht so ganz sicher wohin hier ein weiter experimentieren führt:

Code: Alles auswählen

If CreateImage(0, Frame\right, Frame\bottom, 32, #PB_Image_Transparent)
  StartDrawing(ImageOutput(0))
  DrawingMode(#PB_2DDrawing_AllChannels) ;?
  Box(0, 0, OutputWidth(), OutputHeight(), RGB(255,0,0))
  StopDrawing()
EndIf

DrawTransparentImage(hdc, ImageID(0), 0, 0, ImageWidth(0), ImageHeight(0), RGB(0,0,0))
SetClassLongPtr_(hwnd, -10, CreateSolidBrush_(RGB(255, 0, 0))) ;-10 = SetWindowColor()
;InvalidateRect_(hdc, @Frame, #True)
;SetWindowLongPtr_(hw, #GWL_EXSTYLE, GetWindowLongPtr_(hw, #GWL_EXSTYLE) | #WS_EX_LAYERED)
SetLayeredWindowAttributes_(hw, RGB(255, 0, 0), 0, #LWA_COLORKEY)
;SetLayeredWindowAttributes_(hw, RGB(255, 255, 255), 255, #LWA_ALPHA)

RedrawWindow_( hw, @Frame, 0, #RDW_NOERASE | #RDW_INVALIDATE | #RDW_UPDATENOW | #RDW_ALLCHILDREN)
Das hier ist geil! (Damit ist nicht der Hintergrund rot, sondern die Icons) :mrgreen:

Code: Alles auswählen

Structure lvbkimage
  ulflags.i
  hbm.i
  pszImage.i
  cchImageMax.i
  xOffsetPercent.i
  yOffsetPercent.i
EndStructure
Global bild.lvbkimage
bild\ulflags = 1
bild\hbm = ImageID(0)

DrawTransparentImage(hdc, ImageID(0), 0, 0, ImageWidth(0), ImageHeight(0), RGB(0,0,0))
;SetClassLongPtr_(hwnd, -10, CreateSolidBrush_(RGB(255, 0, 0))) ;-10 = SetWindowColor()
;InvalidateRect_(hdc, @Frame, #True)
;SetWindowLongPtr_(hw, #GWL_STYLE, GetWindowLongPtr_(hw, #GWL_EXSTYLE) | #WS_EX_LAYERED)
;SetLayeredWindowAttributes_(hw, RGB(255, 0, 0), 0, #LWA_COLORKEY)
;SetLayeredWindowAttributes_(hw, RGB(255, 255, 255), 255, #LWA_ALPHA)

SendMessage_(hw,#LVM_SETBKIMAGE,0, bild) ;ListViewImage

RedrawWindow_( hw, @Frame, 0, #RDW_NOERASE | #RDW_VALIDATE | #RDW_UPDATENOW | #RDW_ALLCHILDREN)
Betriebssysteme: div. Windows, Linux, Unix - Systeme

no Keyboard, press any key
no mouse, you need a cat
Benutzeravatar
tft
Beiträge: 605
Registriert: 08.09.2004 20:18
Computerausstattung: GTX Titan , i9 9900K , 32 GB Ram , 500 GB SSD , 3 ASUS FullHD Monitore and more
Wohnort: Dachsen
Kontaktdaten:

Re: Desktop Hintergrund DC ermitteln

Beitrag von tft »

Hallo,

der Ramen wird aber nicht auf dem Hintergrund, sondern auf das Desktopfenster gezeichnet. Dadurch werden die Icons einmalig überschrieben. Bei anklicken des Icon wird der Rote Ramen an der stelle gelöscht.

Gruss TFT
TFT seid 1989 , Turgut Frank Temucin , Dachsen/Berlin/Antalya
Aktuelles Projekte : Driving School Evergarden
YouTube : Pure Basic to go
FaceBook : Temuçin SourceMAgic Games
DISCORD : SourceMagic
W10 , i9 9900K ,32 GB Ram , GTX Titan , 3 Monitore FHD
ARDUINO Freak :-)
Benutzeravatar
Larissa22
Beiträge: 3
Registriert: 25.12.2020 22:44

Re: Desktop Hintergrund DC ermitteln

Beitrag von Larissa22 »

Kann man nicht einfach das Hintergrundbild laden, drauf zeichnen und als Hintergrundbild neu setzen ??
ccode_new
Beiträge: 1214
Registriert: 27.11.2016 18:13
Wohnort: Erzgebirge

Re: Desktop Hintergrund DC ermitteln

Beitrag von ccode_new »

@Larissa22
Larissa22 hat geschrieben:Kann man nicht einfach das Hintergrundbild laden, drauf zeichnen und als Hintergrundbild neu setzen ??
Natürlich kann man das. :roll:
Aber diese Methode ist ja voll uncool und nicht für Animationen geeignet.
Oder?

@tft
Was hast du eigentlich so richtig vor?
Betriebssysteme: div. Windows, Linux, Unix - Systeme

no Keyboard, press any key
no mouse, you need a cat
Axolotl
Beiträge: 146
Registriert: 31.12.2008 16:34

Re: Desktop Hintergrund DC ermitteln

Beitrag von Axolotl »

Ich weiß ja nicht wo ihr hinwollt...
Da es sich ja alles um standard fenster handelt, wird wohl auch das angezeigte "hintergrund-fenster" mit Standardnachrichten arbeiten.

Dann müsste man doch irgendwie hier ProgMan->SHELLDLL_DefView->SysListView32 einen subclass callback oder hook ansetzen, damit man an das WM_ERASEBKGND kommt.
Hier kann man dann malen bis der Arzt kommen.

Nur meine 2 Ct.
Mostly running PureBasic <latest stable version and current alpha/beta> (x64) on Windows 11 Home
ccode_new
Beiträge: 1214
Registriert: 27.11.2016 18:13
Wohnort: Erzgebirge

Re: Desktop Hintergrund DC ermitteln

Beitrag von ccode_new »

Hi Axolotl!

Dann poste mal ne Lösung. :mrgreen:

__________
Gibt es denn eine Möglichkeit um ein Bild aus dem Arbeitsspeicher direkt als Hintergrundbild zu setzten?

Das hier:

Code: Alles auswählen

SystemParametersInfo_(#SPI_SETDESKWALLPAPER, 1, "Dein_lokales_Bild.jpg", #SPIF_UPDATEINIFILE | #SPIF_SENDCHANGE)
ist irgendwie nicht so toll.
Betriebssysteme: div. Windows, Linux, Unix - Systeme

no Keyboard, press any key
no mouse, you need a cat
Benutzeravatar
tft
Beiträge: 605
Registriert: 08.09.2004 20:18
Computerausstattung: GTX Titan , i9 9900K , 32 GB Ram , 500 GB SSD , 3 ASUS FullHD Monitore and more
Wohnort: Dachsen
Kontaktdaten:

Re: Desktop Hintergrund DC ermitteln

Beitrag von tft »

@ccode_new : Ich möchte sowas wie die Wallpaper Engin von Steam in PB realisieren. Weil ich einige Anwendungen für mein Büro als Hintergrund haben möchte. Und dann möchte ich das noch mit der Bass DLL verbinden.

Gruss TFT
TFT seid 1989 , Turgut Frank Temucin , Dachsen/Berlin/Antalya
Aktuelles Projekte : Driving School Evergarden
YouTube : Pure Basic to go
FaceBook : Temuçin SourceMAgic Games
DISCORD : SourceMagic
W10 , i9 9900K ,32 GB Ram , GTX Titan , 3 Monitore FHD
ARDUINO Freak :-)
Benutzeravatar
tft
Beiträge: 605
Registriert: 08.09.2004 20:18
Computerausstattung: GTX Titan , i9 9900K , 32 GB Ram , 500 GB SSD , 3 ASUS FullHD Monitore and more
Wohnort: Dachsen
Kontaktdaten:

Re: Desktop Hintergrund DC ermitteln

Beitrag von tft »

Hier gibt es was auf Englisch ... aber ich versteh das meiste nicht.

https://www.codeproject.com/Articles/85 ... ndows-plus

Gruss TFT
TFT seid 1989 , Turgut Frank Temucin , Dachsen/Berlin/Antalya
Aktuelles Projekte : Driving School Evergarden
YouTube : Pure Basic to go
FaceBook : Temuçin SourceMAgic Games
DISCORD : SourceMagic
W10 , i9 9900K ,32 GB Ram , GTX Titan , 3 Monitore FHD
ARDUINO Freak :-)
Benutzeravatar
Kiffi
Beiträge: 10621
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: Desktop Hintergrund DC ermitteln

Beitrag von Kiffi »

tft hat geschrieben:Ich möchte sowas wie die Wallpaper Engin von Steam in PB realisieren.
3.99€? Und dafür dieser Aufwand?
Hygge
Antworten