Seite 2 von 3

Re: Desktop Hintergrund DC ermitteln

Verfasst: 15.01.2021 01:11
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:

Re: Desktop Hintergrund DC ermitteln

Verfasst: 15.01.2021 21:22
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)

Re: Desktop Hintergrund DC ermitteln

Verfasst: 16.01.2021 16:00
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

Re: Desktop Hintergrund DC ermitteln

Verfasst: 16.01.2021 17:46
von Larissa22
Kann man nicht einfach das Hintergrundbild laden, drauf zeichnen und als Hintergrundbild neu setzen ??

Re: Desktop Hintergrund DC ermitteln

Verfasst: 16.01.2021 18:16
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?

Re: Desktop Hintergrund DC ermitteln

Verfasst: 16.01.2021 18:22
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.

Re: Desktop Hintergrund DC ermitteln

Verfasst: 16.01.2021 18:38
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.

Re: Desktop Hintergrund DC ermitteln

Verfasst: 17.01.2021 00:33
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

Re: Desktop Hintergrund DC ermitteln

Verfasst: 17.01.2021 00:52
von tft
Hier gibt es was auf Englisch ... aber ich versteh das meiste nicht.

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

Gruss TFT

Re: Desktop Hintergrund DC ermitteln

Verfasst: 17.01.2021 00:54
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?