Page 2 of 2

Re: Remove Window Flicker

Posted: Wed Jun 06, 2012 7:08 pm
by netmaestro
I removed the GrabImage and the ImageGadget altogether and it still wobbles:

Code: Select all

Procedure MoveWindow(void)
  Repeat
    If GetAsyncKeyState_(#VK_LBUTTON)&32768
      xpos = WindowX(0)
      ypos = WindowY(0)
      hDCin = CreateCompatibleDC_(0)
      SelectObject_(hDCin, ImageID(1))
      hDCout = StartDrawing(WindowOutput(0))
        BitBlt_(hDCout, 0, 0, 200, 200, hDCin, xpos, ypos ,#SRCCOPY)
      StopDrawing()
      DeleteDC_(hDCin)
    EndIf
    Delay(1)
    
  ForEver
EndProcedure

Procedure OpenWindowMagnify() 
  If OpenWindow(0, 0, 0, 200, 200, "Magnify", #PB_Window_ScreenCentered|#PB_Window_BorderLess)
    ;   SetWindowLongPtr_(WindowID(0), #GWL_EXSTYLE, #WS_EX_LAYERED)
    ;   SetLayeredWindowAttributes_(WindowID(0), 0, #Null, #LWA_COLORKEY)
    StickyWindow(0, 1)
    Region = CreateEllipticRgn_(0, 0, 200, 200)
    SetWindowRgn_(WindowID(0), Region, #True)
    DeleteObject_(Region)
  EndIf
EndProcedure

UseJPEGImageDecoder()
LoadImage(1, "C:\test.jpg")
OpenWindowMagnify()
GrabImage(1, 2, WindowX(0), WindowY(0), 200, 200)
hDCin = CreateCompatibleDC_(0)
SelectObject_(hDCin, ImageID(1))
hDCout = StartDrawing(WindowOutput(0))
  BitBlt_(hDCout, 0, 0, 200, 200, hDCin, WindowX(0), WindowY(0) ,#SRCCOPY)
StopDrawing()
DeleteDC_(hDCin)
CreateThread(@MoveWindow(),0)

Repeat
  Select WaitWindowEvent()
      
    Case #WM_LBUTTONDOWN 
      SendMessage_(WindowID(0), #WM_NCLBUTTONDOWN, #HTCAPTION, #Null) 
      
    Case #WM_LBUTTONDBLCLK
      CloseWindow(0)
      FreeImage(1)
      End
      
  EndSelect
ForEver

Re: Remove Window Flicker

Posted: Wed Jun 06, 2012 7:25 pm
by breeze4me
Try this one, it seems to be no wobbles on my computer. (Win 7 x86, PB 4.61)


Edit: On Win7 x64(virtual machine), there is a wobble. With the classic theme of Windows, no wobble.
Edit2: the code modified.

Code: Select all

Prototype ptDwmIsCompositionEnabled(*pfEnabled)
Prototype ptDwmFlush()
Global DwmIsCompositionEnabled.ptDwmIsCompositionEnabled
Global DwmFlush.ptDwmFlush

If OSVersion() >= #PB_OS_Windows_Vista
  If OpenLibrary(0, "Dwmapi.dll")
    DwmIsCompositionEnabled = GetFunction(0, "DwmIsCompositionEnabled")
    DwmFlush = GetFunction(0, "DwmFlush")
  EndIf
EndIf

Global quit

#OldWndProc = "myoldwprc"

Global StartWinX, StartWinY, PrevMouseX, PrevMouseY, LDown

Procedure DrawImg(x, y)
  Protected Result
  If StartDrawing(WindowOutput(0))
    newImage = GrabImage(1, #PB_Any, x + 200, y + 200, 200, 200)
    If newImage
      DrawImage(ImageID(newImage), 0, 0)
      SetGadgetState(0, ImageID(newImage))
      FreeImage(newImage)
    EndIf
    StopDrawing()
  EndIf
  If DwmFlush And DwmIsCompositionEnabled
    DwmIsCompositionEnabled(@Result)
    If Result
      DwmFlush()
    EndIf
  EndIf
EndProcedure

Procedure WindowProc(hWnd, uMsg, wParam, lParam)
  Protected old = GetProp_(hWnd, #OldWndProc)
  
  Select uMsg
    Case #WM_ERASEBKGND
      ProcedureReturn 0
      
    Case #WM_PAINT
      DrawImg(WindowX(0), WindowY(0))
      
    Case #WM_LBUTTONDOWN
      LDown = 1
      StartWinX = WindowX(0)
      StartWinY = WindowY(0)
      
      GetCursorPos_(p.POINT)
      PrevMouseX = p\x
      PrevMouseY = p\y
      
    Case #WM_LBUTTONUP
      LDown = 0
      
    Case #WM_LBUTTONDBLCLK
      quit = 1
      
    Case #WM_NCDESTROY
      RemoveProp_(hWnd, #OldWndProc)
      
  EndSelect
  
  ProcedureReturn CallWindowProc_(old, hWnd, uMsg, wParam, lParam)
EndProcedure

Procedure OpenWindowMagnify() 
  If OpenWindow(0, 0, 0, 200, 200, "Magnify", #PB_Window_ScreenCentered|#PB_Window_BorderLess)
   ;SetWindowLongPtr_(WindowID(0), #GWL_EXSTYLE, #WS_EX_LAYERED)
   ;SetLayeredWindowAttributes_(WindowID(0), 0, #Null, #LWA_COLORKEY)
    StickyWindow(0, 1)
    Region = CreateEllipticRgn_(0, 0, 200, 200)
    SetWindowRgn_(WindowID(0), Region, #True)
    DeleteObject_(Region)
    SetProp_(WindowID(0), #OldWndProc, SetWindowLongPtr_(WindowID(0), #GWLP_WNDPROC, @WindowProc()))
  EndIf
EndProcedure

OpenWindow(1, 700, 0, 200, 200,  "", #PB_Window_BorderLess)
ImageGadget(0, 0, 0, 200, 200, 0)

UseJPEGImageDecoder()

If LoadImage(2, "c:\test.jpg")
  If CreateImage(1, ImageWidth(2) + 200, ImageHeight(2) + 200)
    StartDrawing(ImageOutput(1))
    DrawImage(ImageID(2), 200, 200)
    StopDrawing()
  EndIf
  FreeImage(2)
EndIf


OpenWindowMagnify()


Repeat
  ;event = WaitWindowEvent()
  event = WaitWindowEvent(1)
  
  If LDown
    GetCursorPos_(p.POINT)
    SetWindowPos_(WindowID(0), 0, StartWinX + p\x - PrevMouseX, StartWinY + p\y - PrevMouseY, 200, 200, #SWP_NOZORDER | #SWP_NOCOPYBITS)
  EndIf
  
Until quit = 1 Or event = #PB_Event_CloseWindow Or GetAsyncKeyState_(#VK_ESCAPE) & $8001

CloseWindow(0)
FreeImage(1)

Re: Remove Window Flicker

Posted: Wed Jun 06, 2012 9:16 pm
by IdeasVacuum
using CopyImage after the GrabImage
Not surprised that failed, destined to make the issue worst I think. The idea was to avoid GrabImage() being in the loop.

Re: Remove Window Flicker

Posted: Wed Jun 06, 2012 9:20 pm
by IdeasVacuum
breeze4me
Edit2: the code modified.
Way Hey! That one works perfectly on my XP 32bit PC (Theme on too).

Re: Remove Window Flicker

Posted: Wed Jun 06, 2012 9:21 pm
by JHPJHP
IdeasVacuum - I think at that point I was prepared to try anything.

netmaestro - you pretty much concluded that it's not a PB thing - thank you.

breeze4me - what planet are you from? I can understand the steps it took to substitute SendMessage for GetCursorPos and SetWindowPos, but the Dwm commands?.. seriously nice job.

IdeasVacuum
netmaestro
breeze4me

I can only say thank you so many times (before I'm considered a nut!) - but I'll test fate one more time.

Thank you all,

Re: Remove Window Flicker

Posted: Thu Jun 07, 2012 7:20 pm
by JHPJHP
Hi again,

Moved around some of netmaestro & breeze4me's code to tweek the results, tried a few variations, kept one (rem'd out), but adding a constraint (CallBack) in placement of the Repeat/Forever Loop (thread) diminished results - slightly.

With the few added functions the effect is a cursor magnifying glass (only clearer if dealing with resized images) - exactly what I was after.

Thanks again guys,

Code: Select all

Prototype ptDwmIsCompositionEnabled(*pfEnabled)
Prototype ptDwmFlush()
Global DwmIsCompositionEnabled.ptDwmIsCompositionEnabled
Global DwmFlush.ptDwmFlush
Global DwmResult, hDCin, glassSize

Procedure OpenWindowMagnify() 
  If OpenWindow(0, 0, 0, glassSize, glassSize, "Magnify", #PB_Window_ScreenCentered | #PB_Window_BorderLess)
    StickyWindow(0, 1)
    winRegion = CreateEllipticRgn_(0, 0, glassSize, glassSize)
    SetWindowRgn_(WindowID(0), winRegion, #True)
    DeleteObject_(winRegion)
  EndIf
EndProcedure

Procedure DrawImg()
  hDCout = StartDrawing(WindowOutput(0))
    BitBlt_(hDCout, 0, 0, glassSize, glassSize, hDCin, WindowX(0), WindowY(0), #SRCCOPY)
  StopDrawing()
EndProcedure

Procedure MoveWindow(void)
  Repeat
    GetCursorPos_(p.POINT)
    xpos = p\x - (glassSize / 2)
    ypos = p\y - (glassSize) / 2)
    SetWindowPos_(WindowID(0), 0, xpos, ypos, glassSize, glassSize, #SWP_NOZORDER | #SWP_NOCOPYBITS)
    DrawImg()
    
    If DwmResult : DwmFlush() : EndIf
    
  ForEver
EndProcedure

; Procedure MoveWindow(hWnd, uMsg, wParam, lParam)
  ; Result = #PB_ProcessPureBasicEvents
  ; 
  ; Select uMsg
    ; Case #WM_SETCURSOR, #WM_PAINT, #WM_MOVING
      ; GetCursorPos_(p.POINT)
      ; xpos = p\x - (glassSize / 2)
      ; ypos = p\y - (glassSize) / 2)
      ; SetWindowPos_(WindowID(0), 0, xpos, ypos, glassSize, glassSize, #SWP_NOZORDER | #SWP_NOCOPYBITS)
      ; DrawImg()
      ; 
      ; If DwmResult : DwmFlush() : EndIf
      ; 
  ; EndSelect
  ; ProcedureReturn Result
; EndProcedure

If OSVersion() >= #PB_OS_Windows_Vista
  If OpenLibrary(0, "Dwmapi.dll")
    DwmIsCompositionEnabled = GetFunction(0, "DwmIsCompositionEnabled")
    DwmFlush = GetFunction(0, "DwmFlush")
    
    If DwmFlush And DwmIsCompositionEnabled : DwmIsCompositionEnabled(@DwmResult) : EndIf
    
  EndIf
EndIf
UseJPEGImageDecoder()
LoadImage(1, "C:\test.jpg")
glassSize = 200
OpenWindowMagnify()
ShowCursor_(0)
hDCin = CreateCompatibleDC_(0)
SelectObject_(hDCin, ImageID(1))
DrawImg()

If DwmResult : DwmFlush() : EndIf

CreateThread(@MoveWindow(), 0)
;SetWindowCallback(@MoveWindow())

Repeat
  Select WaitWindowEvent() 
    Case #WM_LBUTTONDBLCLK
      DeleteDC_(hDCin)
      ShowCursor_(1)
      CloseWindow(0)
      FreeImage(1)
      Break
  EndSelect
ForEver

Re: Remove Window Flicker

Posted: Thu Jun 07, 2012 7:40 pm
by RASHAD
Tested with Win 7 x64

Code: Select all

Global quit

#OldWndProc = "myoldwprc"

Global StartWinX, StartWinY, PrevMouseX, PrevMouseY, LDown

Procedure DrawImg(x, y)
  Protected Result
  If StartDrawing(WindowOutput(0))
    newImage = GrabImage(1, #PB_Any, x + 200, y + 200, 200, 200)
    If newImage
      DrawImage(ImageID(newImage), 0, 0)
      FreeImage(newImage)
    EndIf
    StopDrawing()
  EndIf
EndProcedure

Procedure WindowProc(hWnd, uMsg, wParam, lParam)
  Protected old = GetProp_(hWnd, #OldWndProc)
  
  Select uMsg
    Case #WM_ERASEBKGND
      ProcedureReturn 0
      
    Case #WM_PAINT
      DrawImg(WindowX(0), WindowY(0))
      
    Case #WM_LBUTTONDOWN
      LDown = 1
      StartWinX = WindowX(0)
      StartWinY = WindowY(0)
      
      GetCursorPos_(p.POINT)
      PrevMouseX = p\x
      PrevMouseY = p\y
      
    Case #WM_LBUTTONUP
      LDown = 0
      
    Case #WM_LBUTTONDBLCLK
      quit = 1
      
    Case #WM_NCDESTROY
      RemoveProp_(hWnd, #OldWndProc)
      
  EndSelect
  
  ProcedureReturn CallWindowProc_(old, hWnd, uMsg, wParam, lParam)
EndProcedure

Procedure OpenWindowMagnify() 
  If OpenWindow(0, 0, 0, 200, 200, "Magnify", #PB_Window_ScreenCentered|#PB_Window_BorderLess)
    StickyWindow(0, 1)
    Region = CreateEllipticRgn_(0, 0, 200, 200)
    SetWindowRgn_(WindowID(0), Region, #True)
    DeleteObject_(Region)
    SetProp_(WindowID(0), #OldWndProc, SetWindowLongPtr_(WindowID(0), #GWLP_WNDPROC, @WindowProc()))
  EndIf
EndProcedure



If OSVersion() >= #PB_OS_Windows_Vista
  OpenLibrary(0, "dwmapi.dll")
  *comp=GetFunction(0,"DwmEnableComposition")
  CallFunctionFast(*comp,0)
EndIf

UseJPEGImageDecoder()

If LoadImage(2, "g:\1234_619647.jpg")
  If CreateImage(1, ImageWidth(2) + 200, ImageHeight(2) + 200)
    StartDrawing(ImageOutput(1))
    DrawImage(ImageID(2), 200, 200)
    StopDrawing()
  EndIf
  FreeImage(2)
EndIf


OpenWindowMagnify()


Repeat
  event = WaitWindowEvent(1)
  
  If LDown
    GetCursorPos_(p.POINT)
    SetWindowPos_(WindowID(0), 0, StartWinX + p\x - PrevMouseX, StartWinY + p\y - PrevMouseY, 200, 200, #SWP_NOZORDER | #SWP_NOCOPYBITS)
  EndIf
  
Until quit = 1 Or event = #PB_Event_CloseWindow Or GetAsyncKeyState_(#VK_ESCAPE) & $8001

If IsLibrary(0)
    CloseLibrary(0)
EndIf 
CloseWindow(0)
FreeImage(1)

Edit : Code updated for Win XP & Win 7 ,Not tested with Vista but it should work as expected

Re: Remove Window Flicker

Posted: Thu Jun 07, 2012 11:59 pm
by IdeasVacuum
Hi JHPJHP

On WinXP 32bit, I see no wobble with your code but there is a definite flicker.

Rashad's code looks to be Win7 only, I have not tried it but usually you can bank on Rashad to pull a rabbit out of the hat 8)

Re: Remove Window Flicker

Posted: Fri Jun 08, 2012 6:56 am
by JHPJHP
Thanks IdeasVacuum, at home I'm only on Windows 7 - 64 bit, but I'm going to create a VMWare XP - SP3 box to test with.

RASHAD - like the addition... Code to change the color scheme will definitely come in handy.

Re: Remove Window Flicker

Posted: Wed Oct 10, 2012 5:38 am
by JHPJHP
Hi,

As I continued to write the application I was working on, where a small part was the Magnifier (which this thread is all about) - I kept revisiting the flicker issue. Even with all the fantastic help that I received - the flicker remained; greatly reduced because of the help, but still noticable.

Funny enough I went back to one of my first solutions / observations - by adding the following two lines of code - the flicker disappeared:

Code: Select all

SetWindowLongPtr_(WindowID(0), #GWL_EXSTYLE, #WS_EX_LAYERED)
SetLayeredWindowAttributes_(WindowID(0), 0, #Null, #LWA_COLORKEY)
But setting the window to layered / transparent - wasn't a usable option so I quickly moved on...

Rethinking things (after numerous failed solutions - on my part) why couldn't I use it - just change the transparent color to one that would never occur (at least within this context):

Code: Select all

SetWindowLongPtr_(WindowID(0), #GWL_EXSTYLE, #WS_EX_LAYERED)
SetLayeredWindowAttributes_(WindowID(0), RGB(124, 109, 146), #Null, #LWA_COLORKEY)
Maybe I'm jumping the gun, but in every test so far - no flicker - thought I'd share:

NB*: If this thread is of interest to you, and can help in any way - don't just rely on this last post - some really relevant code form some great scripters (which this example draws from) occurs earlier in the thread, and may be of more use.

Code: Select all

Prototype ptDwmIsCompositionEnabled(*pfEnabled)
Prototype ptDwmFlush()
Global DwmIsCompositionEnabled.ptDwmIsCompositionEnabled
Global DwmFlush.ptDwmFlush
Global DwmResult, hDCin, glassSize

Procedure OpenWindowMagnify() 
  If OpenWindow(0, 0, 0, glassSize, glassSize, "Magnify", #PB_Window_ScreenCentered | #PB_Window_BorderLess)
    SetWindowLongPtr_(WindowID(0), #GWL_EXSTYLE, #WS_EX_LAYERED)
    SetLayeredWindowAttributes_(WindowID(0), RGB(124, 109, 146), #Null, #LWA_COLORKEY)
    StickyWindow(0, 1)
    winRegion = CreateEllipticRgn_(0, 0, glassSize, glassSize)
    SetWindowRgn_(WindowID(0), winRegion, #TRUE)
    DeleteObject_(winRegion)
  EndIf
EndProcedure

Procedure DrawImg()
  hDCout = StartDrawing(WindowOutput(0))
    BitBlt_(hDCout, 0, 0, glassSize, glassSize, hDCin, WindowX(0), WindowY(0), #SRCCOPY)
  StopDrawing()
EndProcedure

Procedure MoveWindow(void)
  Repeat
    GetCursorPos_(p.POINT)
    xpos = p\x - (glassSize / 2)
    ypos = p\y - (glassSize / 2)
    SetWindowPos_(WindowID(0), 0, xpos, ypos, glassSize, glassSize, #SWP_NOZORDER | #SWP_NOCOPYBITS)
    DrawImg()
    
    If DwmResult : DwmFlush() : EndIf
    
  ForEver
EndProcedure

If OSVersion() >= #PB_OS_Windows_Vista
  If OpenLibrary(0, "Dwmapi.dll")
    DwmIsCompositionEnabled = GetFunction(0, "DwmIsCompositionEnabled")
    DwmFlush = GetFunction(0, "DwmFlush")
    
    If DwmFlush And DwmIsCompositionEnabled : DwmIsCompositionEnabled(@DwmResult) : EndIf
    
  EndIf
EndIf
UseJPEGImageDecoder()
LoadImage(1, "C:\test.jpg")
glassSize = 200
OpenWindowMagnify()
ShowCursor_(0)
hDCin = CreateCompatibleDC_(0)
SelectObject_(hDCin, ImageID(1))
DrawImg()

If DwmResult : DwmFlush() : EndIf

CreateThread(@MoveWindow(), 0)

Repeat
  Select WaitWindowEvent() 
    Case #WM_LBUTTONDBLCLK
      DeleteDC_(hDCin)
      ShowCursor_(1)
      CloseWindow(0)
      FreeImage(1)
      Break
  EndSelect
ForEver