It is currently Fri May 24, 2013 8:05 pm

All times are UTC + 1 hour




Post new topic Reply to topic  [ 25 posts ]  Go to page Previous  1, 2
Author Message
 Post subject: Re: Remove Window Flicker
PostPosted: Wed Jun 06, 2012 7:08 pm 
Offline
PureBasic Bullfrog
PureBasic Bullfrog
User avatar

Joined: Wed Jul 06, 2005 5:42 am
Posts: 6465
I removed the GrabImage and the ImageGadget altogether and it still wobbles:
Code:
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

_________________
Veni, vidi, vici.


Top
 Profile  
 
 Post subject: Re: Remove Window Flicker
PostPosted: Wed Jun 06, 2012 7:25 pm 
Offline
Enthusiast
Enthusiast

Joined: Thu Mar 09, 2006 9:24 am
Posts: 195
Location: S. Kor
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:
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)


Top
 Profile  
 
 Post subject: Re: Remove Window Flicker
PostPosted: Wed Jun 06, 2012 9:16 pm 
Offline
Addict
Addict

Joined: Fri Oct 23, 2009 2:33 am
Posts: 2863
Location: Wales, UK
Quote:
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.

_________________
IdeasVacuum
If it sounds simple, you have not grasped the complexity.


Top
 Profile  
 
 Post subject: Re: Remove Window Flicker
PostPosted: Wed Jun 06, 2012 9:20 pm 
Offline
Addict
Addict

Joined: Fri Oct 23, 2009 2:33 am
Posts: 2863
Location: Wales, UK
breeze4me
Quote:
Edit2: the code modified.
Way Hey! That one works perfectly on my XP 32bit PC (Theme on too).

_________________
IdeasVacuum
If it sounds simple, you have not grasped the complexity.


Top
 Profile  
 
 Post subject: Re: Remove Window Flicker
PostPosted: Wed Jun 06, 2012 9:21 pm 
Offline
User
User

Joined: Sat Oct 09, 2010 3:47 am
Posts: 56
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 - and if you don't mind i'll be scooping up that code as well :)

breeze4me - what planet are you from? I can understand the steps it took to substitute SendMessage for GetCursorPos and SetWindowPos, but the Dwm commands? :D I wish there was a smilie for me standing and clapping... 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,


Top
 Profile  
 
 Post subject: Re: Remove Window Flicker
PostPosted: Thu Jun 07, 2012 7:20 pm 
Offline
User
User

Joined: Sat Oct 09, 2010 3:47 am
Posts: 56
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:
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


Last edited by JHPJHP on Thu Jun 07, 2012 8:11 pm, edited 2 times in total.

Top
 Profile  
 
 Post subject: Re: Remove Window Flicker
PostPosted: Thu Jun 07, 2012 7:40 pm 
Offline
Addict
Addict

Joined: Sun Apr 12, 2009 6:27 am
Posts: 1473
Tested with Win 7 x64

Code:
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

_________________
Egypt my love


Last edited by RASHAD on Fri Jun 08, 2012 12:25 am, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: Remove Window Flicker
PostPosted: Thu Jun 07, 2012 11:59 pm 
Offline
Addict
Addict

Joined: Fri Oct 23, 2009 2:33 am
Posts: 2863
Location: Wales, UK
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)

_________________
IdeasVacuum
If it sounds simple, you have not grasped the complexity.


Top
 Profile  
 
 Post subject: Re: Remove Window Flicker
PostPosted: Fri Jun 08, 2012 6:56 am 
Offline
User
User

Joined: Sat Oct 09, 2010 3:47 am
Posts: 56
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.


Top
 Profile  
 
 Post subject: Re: Remove Window Flicker
PostPosted: Wed Oct 10, 2012 5:38 am 
Offline
User
User

Joined: Sat Oct 09, 2010 3:47 am
Posts: 56
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:
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:
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:
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


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 25 posts ]  Go to page Previous  1, 2

All times are UTC + 1 hour


Who is online

Users browsing this forum: AgManiX, skywalk and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  

 


Powered by phpBB © 2008 phpBB Group
subSilver+ theme by Canver Software, sponsor Sanal Modifiye