Jump to content
Sign in to follow this  
Artisan

Help with BitBlt

Recommended Posts

Artisan

I'm coding a GUI that using a lot of GDI (not GDI+) output.  I've been manually redrawing things as needed via WM_PAINT.  It's awkward and slow, and it can flicker a lot.  Then I found out about _WinAPI_BitBlt.  I've looked all over the forums here, and all over the internet in general.  I think I understand the basics of it, but I can't get it to work.  I think what I want to do is manipulate $hDCSource and then BitBlt it onto $hDCDest.  Here's my reducer sample:

#include <GUIConstantsEx.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>

Global Const $Width = 100, $Height = 100
Global $Left = 50, $Top = 50
Global $hwnd, $hDCDest, $hDCSource, $hPenLil, $hPenFat, $hBrush
Main()

Func Main()

    ; GUI & GDI handles
    $hwnd = GUICreate("BitBlt Test", 300, 300)
    $hDCDest = _WinAPI_GetDC($hwnd)
    $hDCSource = _WinAPI_CreateCompatibleDC($hDCDest)
    $hPenLil = _WinAPI_CreatePen($PS_SOLID, 1, 0xFFFFFF)
    $hPenFat = _WinAPI_CreatePen($PS_SOLID, 3, 0x00FF00)
    $hBrush = _WinAPI_CreateSolidBrush(0xFFFFFF)

    ; Fill white rectangle
    Local $tRect = DllStructCreate($tagRect)
        DllStructSetData($tRect, "Left", $Left)
        DllStructSetData($tRect, "Top", $Top)
        DllStructSetData($tRect, "Right", $Left + $Width)
        DllStructSetData($tRect, "Bottom", $Top + $Height)
    _WinAPI_FillRect($hDCSource, $tRect, $hBrush)

    ; Thick green outline
    _WinAPI_SelectObject($hDCSource, $hPenFat)
    _WinAPI_MoveTo($hDCSource, $Left, $Top)
    _WinAPI_LineTo($hDCSource, $Left + $Width, $Top)
    _WinAPI_LineTo($hDCSource, $Left + $Width, $Top + $Height)
    _WinAPI_LineTo($hDCSource, $Left, $Top + $Height)
    _WinAPI_LineTo($hDCSource, $Left, $Top)

    ; Thin black outline
    _WinAPI_SelectObject($hDCSource, $hPenLil)
    _WinAPI_MoveTo($hDCSource, $Left, $Top)
    _WinAPI_LineTo($hDCSource, $Left + $Width, $Top)
    _WinAPI_LineTo($hDCSource, $Left + $Width, $Top + $Height)
    _WinAPI_LineTo($hDCSource, $Left, $Top + $Height)
    _WinAPI_LineTo($hDCSource, $Left, $Top)

    GUIRegisterMsg($WM_PAINT, "WM_PAINT")
    GUISetState(@SW_SHOW, $hwnd)

    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                Quit()
        EndSwitch
    WEnd
EndFunc

Func WM_PAINT()
;   _WinAPI_BitBlt($hDCDest, $Left, $Top, $Width, $Height, $hDCSource, $Left, $Top, $BLACKNESS) ; Works
    _WinAPI_BitBlt($hDCDest, $Left, $Top, $Width, $Height, $hDCSource, $Left, $Top, $SRCCOPY)   ; Doesn't work
EndFunc

Func Quit()
    _WinAPI_ReleaseDC($hwnd, $hDCDest)
    _WinAPI_DeleteDC($hDCSource)
    _WinAPI_DeleteObject($hBrush)
    _WinAPI_DeleteObject($hPenLil)
    _WinAPI_DeleteObject($hPenFat)
    GUIDelete($hwnd)
    Exit
EndFunc

What am I doing wrong?

Share this post


Link to post
Share on other sites
UEZ

You forgot to create the bitmap where you draw your graphics.

#include <GUIConstantsEx.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>

Global Const $Width = 100, $Height = 100
Global $Left = 50, $Top = 50
Global $hwnd, $hDCDest, $hDCSource, $hPenLil, $hPenFat, $hBrush, $hHBitmap
Main()

Func Main()

    ; GUI & GDI handles
    $hwnd = GUICreate("BitBlt Test", 300, 300)
    GUISetState(@SW_SHOW, $hwnd)

    $hDCDest = _WinAPI_GetDC($hwnd)
    $hDCSource = _WinAPI_CreateCompatibleDC($hDCDest)
    $hHBitmap = _WinAPI_CreateSolidBitmap($hwnd, 0, 300, 300)
    _WinAPI_SelectObject($hDCSource, $hHBitmap)

    $hPenLil = _WinAPI_CreatePen($PS_SOLID, 1, 0xFFFFFF)
    $hPenFat = _WinAPI_CreatePen($PS_SOLID, 3, 0x00FF00)
    $hBrush = _WinAPI_CreateSolidBrush(0xFFFFFF)

    ; Fill white rectangle
    Local $tRect = DllStructCreate($tagRect)
        DllStructSetData($tRect, "Left", $Left)
        DllStructSetData($tRect, "Top", $Top)
        DllStructSetData($tRect, "Right", $Left + $Width)
        DllStructSetData($tRect, "Bottom", $Top + $Height)

    _WinAPI_SelectObject($hDCSource, $hBrush)
    _WinAPI_FillRect($hDCSource, $tRect, $hBrush)

    ; Thick green outline
    _WinAPI_SelectObject($hDCSource, $hPenFat)
    _WinAPI_MoveTo($hDCSource, $Left, $Top)
    _WinAPI_LineTo($hDCSource, $Left + $Width, $Top)
    _WinAPI_LineTo($hDCSource, $Left + $Width, $Top + $Height)
    _WinAPI_LineTo($hDCSource, $Left, $Top + $Height)
    _WinAPI_LineTo($hDCSource, $Left, $Top)

    ; Thin black outline
    _WinAPI_SelectObject($hDCSource, $hPenLil)
    _WinAPI_MoveTo($hDCSource, $Left, $Top)
    _WinAPI_LineTo($hDCSource, $Left + $Width, $Top)
    _WinAPI_LineTo($hDCSource, $Left + $Width, $Top + $Height)
    _WinAPI_LineTo($hDCSource, $Left, $Top + $Height)
    _WinAPI_LineTo($hDCSource, $Left, $Top)

    GUIRegisterMsg($WM_PAINT, "WM_PAINT")
    _WinAPI_RedrawWindow($hwnd, 0, 0, $RDW_INVALIDATE + $RDW_UPDATENOW)

    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                Quit()
            Case $GUI_EVENT_RESTORE
                _WinAPI_RedrawWindow($hwnd, 0, 0, $RDW_INVALIDATE + $RDW_UPDATENOW)
        EndSwitch
    WEnd
EndFunc

Func WM_PAINT()
;   _WinAPI_BitBlt($hDCDest, $Left, $Top, $Width, $Height, $hDCSource, $Left, $Top, $BLACKNESS) ; Works
    _WinAPI_BitBlt($hDCDest, $Left, $Top, $Width, $Height, $hDCSource, $Left, $Top, $SRCCOPY)   ; Doesn't work
EndFunc

Func Quit()
    _WinAPI_ReleaseDC($hwnd, $hDCDest)
    _WinAPI_DeleteDC($hDCSource)
    _WinAPI_DeleteObject($hHBitmap)
    _WinAPI_DeleteObject($hBrush)
    _WinAPI_DeleteObject($hPenLil)
    _WinAPI_DeleteObject($hPenFat)
    GUIDelete($hwnd)
    Exit
EndFunc

Br,

UEZ

  • Like 1

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites
Artisan

Thanks again, UEZ!  The helpfile is rather sparse on this topic.  Solved!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Similar Content

    • nacerbaaziz
      By nacerbaaziz
      hi dears, i have an question please if you can help me.
      i maked an program to do some functions
      and this program works with the global hot keys
      i added an option to the users to change the hot keys
      when i searched about how to do that i found this UDF
      GUIHotkey.au3
      http://www.autoitscript.com/forum/index.php?showtopic=107965
      but the problem here that this UDF cant be detect the win key.
      can you help me to add it, or if there are any others UDFSS wich do that work please give me some.
      i hope that my question is clear for you.
      thanks in advance
    • mdepot
      By mdepot
      I have a situation where I am repeatedly capturing a region of the screen and feeding it into Tesseract OCR.  Since the OCR is a relatively slow operation, I would like to create an in memory cache of the ocr results.  An ideal hash key for this cache would be a checksum of the captured image.  With this I could capture the region, checksum it, and then only if I don't get a cache hit I would write the image out to disk for external OCR.
      Now I know I can do this by saving the captured image out to disk, and then summing the disk file with _Crypt_HashFile().  But that's still slower than I would like, and it shouldn't be necessary.  Ideally, it should be possible to checksum the image data directly in memory so I don't have to go to disk at all.  In order to do that, I need a way to dump a representation of the image into a string  (or some equivalent).  Then I could use the _Crypt_HashData() function against that string to create my cache hash key.
      Googling around I found an article here that shows a way to convert an image object to a byte array using System.Drawing.  This was the closest thing I found to what I'm trying to do.  I don't know if that method could be used from within AutoIT, or if perhaps there may be a better way I don't know about.  If someone could give me a shove in the right direction it would be a big help.  Thanks!
    • Silas
      By Silas
      Hello everyone,
      I have a radio button ($Radio1), which I want to disable as soon as another one get's checked (Radio5). (The system fails if the radio button i'm troubling with also gets checked).
      I know how to disable him:
      If GUICtrlRead($Radio1)=1 And Not BitAND(GUICtrlGetState($Radio5), $GUI_DISABLE) Then GUICtrlSetState($Radio5, 128) But if i try to enable $Radio5 again, after $Radio1 isn't checked anymore, it fails:
      If GUICtrlRead($Radio1)=Not 1 And Not BitAND(GUICtrlGetState($Radio5), $GUI_ENABLE) Then GUICtrlSetState($Radio5, 64)  
      Anyone knows why?
    • UEZ
      By UEZ
      Here some graphical examples written completely in FreeBasic just for fun.  
      3D Starfield Rotating Flight 3D Starfield Scrolling v1 Booster 3D Starfield Scrolling v3 Booster CreateWindowEx (hGUI) Example FB File2Bas Code Generator (AutoIt script) FB GFX Examples Fire Particles FMOD Examples GDI - GDI+ 3D Sinus Wave GDI - GDI+ Animated Pythagoras Tree GDI - GDI+ Particles - Repulsive Force Sim v2.0 GDI - GDI+ Plasma v5 Booster GDI - GDI+ Random Pattern GDI - GDI+ Space Flight GDI - GDI+ Tunnel Flight - WipeOut Style GDI Classic Raytraced Tunnel GDI Elastic Twister Effect GDI Exploding Pixels GDI Infinite Image Zoom Flight GDI Liquid Pixels GDI Particle Repulsion Grid GDI Particles Mouse Attraction GDI Starfield GDI The Nautilus Raymarcher GDI Worm Tunnel Flight GDI+ Impossible Possible GDI+ Kaleidoscope GDI+ Performance Test - Au3 vs FB GDI+ Polar Clock GDI+ Rotating Earth GDI+ Star Wars Scroller GDI+ Streamer GDI+ Swiss Railway Clock Ini Read - Write Mandelbrot Plasma Puristic Clock Rutt_Etra_Izer_Booster Tunnel Flight uFMOD _WinAPI_SetWindowTitleIcon  
      Download: FreeBasic Examples build 2018-07-10.rar
       
      I will add new examples from time to time.
       
      FreeBasic source codes are also included.
       
    • Bllee
      By Bllee
      every time i press "delete button" delete a line, but i can't add new line with info. the id line write normally but i can't change or add new info
      obs: looking at the "includes" one realizes that already tried of everything that knew
      my code
      #include <ButtonConstants.au3> #include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <GUIListBox.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> #include <GUIConstantsEx.au3> #include <GuiImageList.au3> #include <GuiListView.au3> #include <GUIConstantsEx.au3> #include <GuiListView.au3> #include <MsgBoxConstants.au3> #include <WinAPI.au3> #include <StringConstants.au3> #include <Array.au3> #include <GuiListBox.au3> #Region ### START Koda GUI section ### Form= $Form1 = GUICreate("Form1", 612, 480, 192, 154) $MenuItem1 = GUICtrlCreateMenu("&Arquivo") $MenuItem2 = GUICtrlCreateMenuItem("Salvar Ctrl+S", $MenuItem1, $SS_CENTER) $MenuItem4 = GUICtrlCreateMenuItem("Carregar Ctrl+O", $MenuItem1, $SS_CENTER) $MenuItem3 = GUICtrlCreateMenuItem("Salvar Como Shitft+Ctrl+S", $MenuItem1, $SS_CENTER) $Group1 = GUICtrlCreateGroup("", 21, 8, 569, 97, $SS_CENTER) $Input1 = GUICtrlCreateInput("ID COR", 122, 32, 97, 21, $SS_CENTER) $Input2 = GUICtrlCreateInput("REGIÃO", 138, 64, 249, 21, $SS_CENTER) $Input3 = GUICtrlCreateInput("Label", 264, 30, 121, 21, $SS_CENTER) $Label1 = GUICtrlCreateLabel("Label", 232, 32, 30, 17, $SS_CENTER) $Button1 = GUICtrlCreateButton("Capturar Cor", 42, 30, 75, 25, $SS_CENTER) $Button2 = GUICtrlCreateButton("Capturar Região", 42, 62, 91, 25, $SS_CENTER) $Button3 = GUICtrlCreateButton("ADD", 442, 24, 113, 33) $Button5 = GUICtrlCreateButton("Delet", 442, 64, 113, 33) $Group2 = GUICtrlCreateGroup("Editar ID selecionado", 8, 384, 601, 57, $SS_CENTER) $Input7 = GUICtrlCreateInput("ID", 10, 402, 40,21, $SS_CENTER) $Input4 = GUICtrlCreateInput("COR", 51, 402, 121, 21, $SS_CENTER) $Input5 = GUICtrlCreateInput("REGIÃO", 173, 402, 249, 21, $SS_CENTER) $Input6 = GUICtrlCreateInput("LABEL", 423, 402, 121, 21, $SS_CENTER) $Button4 = GUICtrlCreateButton("\/", 544, 400, 30, 25, $SS_CENTER) $Button6 = GUICtrlCreateButton("/\", 574, 400, 30, 25, $SS_CENTER) ; Add column Global $id = Int(0) $List1 = GUICtrlCreateListView("",5, 120, 601, 253, $SS_CENTER) _GUICtrlListView_AddColumn($List1, "ID",40) _GUICtrlListView_AddColumn($List1, "COR",100) _GUICtrlListView_AddColumn($List1, "COORDENADA",305) _GUICtrlListView_AddColumn($List1, "LABEL",150) GUISetState(@SW_SHOW) #EndRegion ### END Koda GUI section ### While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit Case $MenuItem2 MsgBox($MB_SYSTEMMODAL, "ctrl + s", "Nothing Here",1) Case $MenuItem3 MsgBox($MB_SYSTEMMODAL, "shift+ctrl s", "Nothing Here",1) Case $MenuItem4 MsgBox($MB_SYSTEMMODAL, "ctrl + o", "Nothing Here",1) Case $Button1 MsgBox($MB_SYSTEMMODAL, "Capturar cor", "Aperte espaço para capturar a cor") GUICtrlSetData($Input1,MouseColor()) Case $Button2 MsgBox($MB_SYSTEMMODAL, "capturar região", "Aperte espaço para capturar a posição inicial") local $mouse = MouseGetPos() $x_init = $mouse[0] $y_init = $mouse[1] MsgBox($MB_SYSTEMMODAL, "capturar região", "Aperte espaço para capturar a posição final") local $mouse = MouseGetPos() $x_end = $mouse[0] $y_end = $mouse[1] GUICtrlSetData($Input2,$x_init&','&$y_init&' ; '&$x_end&','&$y_end) Case $Button3 _GUICtrlListView_AddItem($List1, $id, 1) ; id _GUICtrlListView_AddSubItem($List1, $id, GUICtrlRead($Input1), 1, 1) ;cor _GUICtrlListView_AddSubItem($List1, $id, GUICtrlRead($Input2), 2, 1) ;coordenada _GUICtrlListView_AddSubItem($List1, $id, GUICtrlRead($Input3), 3, 1) ;label $id= $id + 1 Case $Button4 $Item = _GUICtrlListView_GetSelectedIndices($List1) $Sid = _GUICtrlListView_GetItem($List1, Number($Item),0) $Scor = _GUICtrlListView_GetItem($List1, Number($Item),1) $Scord = _GUICtrlListView_GetItem($List1, Number($Item),2) $Slabel = _GUICtrlListView_GetItem($List1, Number($Item),3) ; get info GUICtrlSetData($Input7,$Sid[3]) GUICtrlSetData($Input4,$Scor[3]) GUICtrlSetData($Input5,$Scord[3]) GUICtrlSetData($Input6,$Slabel[3]) Case $Button5 _GUICtrlListView_DeleteItemsSelected($List1) Case $Button6 ; give back inf if GUICtrlRead($Input7) <> "ID" Then _GUICtrlListView_SetItem($List1, GUICtrlRead($Input4), GUICtrlRead($Input7),1) ;cor _GUICtrlListView_SetItem($List1, GUICtrlRead($Input5), GUICtrlRead($Input7),2) ;coordenada _GUICtrlListView_SetItem($List1, GUICtrlRead($Input6), GUICtrlRead($Input7),3) ;coordenada EndIf EndSwitch WEnd Func MouseColor() local $mouse = MouseGetPos() Return Hex(PixelGetColor($mouse[0],$mouse[1]), 6) EndFunc  
×