| 
		
	
	
	
		
	Posts: 1,058Threads: 367
 Joined: Oct 2007
 
	
	
		After having installed and used Adobe Reader XI :
 There exist cases that when using "CaptureImageOrColor" to capture an image, the screen is cleared (it becomes white) while the message-window "Draw a rectangle ..." is only displayed. As a matter of fact nothing is captured. It recovers after some time, I was not able to register which action actually it recovered it. It also recovers when rebooting. Could you please advise. Thanks in advance.
 
	
	
	
		
	Posts: 12,239Threads: 144
 Joined: Dec 2002
 
	
	
		What is your CaptureImageOrColor calling code?Does it happen when you capture image with dialog 'Find image'? It uses CaptureImageOrColor.
 
	
	
	
		
	Posts: 1,058Threads: 367
 Joined: Oct 2007
 
	
	
		This is my rather very simple calling code : 
Function CaptureImage 
Trigger CWci   str si.getmacro(getopt(itemid) 1)if ideb; out "%s : %s" NowT si
 
 ;function# int&result flags [hwndmin] [$bmpfile] [RECT&rect] ;;flags: 0 image, 1 color, 2 minimize owner, 4 disable hwndmin, 8 don't restore if ok
 
 ;Allows the user to capture an image or a color on the screen.
 ;Unlike CaptureImageOnScreen, this function interacts with the user, and returns only when the user clicks OK or Cancel or presses Esc.
 ;If flags contains 1, captures color, else captures image.
 ;Returns 1 if the user clicks OK and everything goes without errors. Returns 0 otherwise.
 
 ;result - variable that will receive color value or bitmap handle. Later the bitmap must be deleted using DeleteObject. Can be 0 if not needed.
 ;hwndmin - handle of a window to be minimized/restored. Can be 0.
 ;bmpfile - if used, saves the image to the file. Returns 0 if fails to save. Can be "".
 ;rect - receives rectangle/point coordinates. Can be 0.
 
 RECT r
 _s.Datim
 str sout.from("C:\tmp\Image_" _s ".bmp")
 
 int i=CaptureImageOrColor(0 0 0 sout r)
 if !i
 ,_s="Failed to capture"
 ,min 0; err out "<>%s : <open ''%s /%i''>%s</open> - %s" NowT si _error.place si _s
 ,mac "Warning_QM" si 0
 ,end
 
 int wid hei x y
 x=r.left
 y=r.top
 wid=r.right-r.left
 hei=r.bottom-r.top
 ;out x
 ;out y
 ;out wid
 ;out hei
 
 __MemBmp b.Create(wid hei 1 x y)
 
 int    q=OpenClipboard(_hwndqm)
 if(q) EmptyClipboard; q=SetClipboardData(CF_BITMAP b.Detach)!0; CloseClipboard
 
 i=rset(sout "ses_last_CI")
 if i=0
 ,_s="You must create a QM registry string value as ''ses_last_CI'' with value data ''***''"
 ,min 0; err out "<>%s : <open ''%s /%i''>%s</open> - %s" NowT si _error.place si _s
 ,mac "Warning_QM" si 0
 ,end
 
 beeS 500 500
 _s.from("Image captured stored to clipboard - also stored to file " sout)
 Task_Message sout 0 255 1
 
	
	
	
		
	Posts: 12,239Threads: 144
 Joined: Dec 2002
 
	
	
		The code is correct, but don't need to capture 2 times. 
Look in Task Manager, maybe QM or some other process uses very much memory or many GDI objects. White screen could be if QM fails to allocate memory for whole screen, it may require 5-10 MB for each monitor, depending on screen size.
 
Function CaptureImage 
Trigger CWc   RECT rstr sout.from("$temp$\Image_" _s ".bmp")
 
 __GdiHandle hBitmap
 int i=CaptureImageOrColor(hBitmap 0 0 sout r)
 if !i
 ,out "Failed to capture"
 ,end
 
 int q=OpenClipboard(_hwndqm)
 if(q) EmptyClipboard; q=SetClipboardData(CF_BITMAP hBitmap)!0; CloseClipboard
 if(q) hBitmap.handle=0
 
 _s.from("Image captured stored to clipboard - also stored to file " sout)
 OnScreenDisplay _s
 
	
	
	
		
	Posts: 1,058Threads: 367
 Joined: Oct 2007
 
	
	
		Dear Gintaras,
 Many thanks for your helpful advice. I will follow it, I am sure it will solve this problem. Kind regards, Simos.
 
	
	
	
		
	Posts: 1,058Threads: 367
 Joined: Oct 2007
 
	
	
		Dear Gintaras,
 I tried to investigate this issue following your hints. I found that one process, namely PSHotFolders, used an increased number of GDI objects. I increased registry value GDIProcessHandleQuota up to about 4000Hex, I experienced some improvement but the problem was not solved. Is it likely that there exists something else that I should try?
 
 Best regards, Simos.
 
	
	
	
		
	Posts: 12,239Threads: 144
 Joined: Dec 2002
 
	
	
		This is a debug version. If some API function fails, shows error there. 
Function CaptureImageOrColor_debug ;/function# int&result flags [hwndmin] [$bmpfile] [RECT&rect] ;;flags: 0 image, 1 color, 2 minimize owner, 4 disable hwndmin, 8 don't restore if ok, 16 no tooltip, 32 no menu
 
 ;A debug version of CaptureImageOrColor.
 
 
 type ___CIOC POINT'p0 RECT'r xs ys cxs cys xmagn !flags !retry !erase !inmenu __MemBmp'bms __MemBmp'bmc
 ___CIOC d.flags=flags
 int i ho R
 
 ;opt err 1
 opt waitmsg 1 ;;caller may be dialog etc
 spe 50
 if(hwndmin)
 ,if(flags&2) ho=GetWindow(hwndmin GW_OWNER)
 ,if(!ho) ho=hwndmin
 ,min ho
 ,if(flags&4) EnableWindow hwndmin 0
 ,0.5
 
 ;g1
 GetVirtualScreen d.xs d.ys d.cxs d.cys
 d.bms.Create_debug(d.cxs d.cys 2) ;;take snapshot
 
 str debugFile="$temp$\CaptureImageOrColor_debug.bmp"
 _i=SaveBitmap(d.bms.bm debugFile)
 if(_i) out F"<>Whole screen bitmap saved here: <link>{debugFile}</link>. Is it white?"
 else out "Failed to save whole screen bitmap"
 
 sel(ShowDialog("" &sub.Dlg 0 0 0 0 0 &d))
 ,case 1 ;;OK
 ,if(flags&1)
 ,,R=1
 ,,if(&result) result=GetPixel(d.bms.dc d.p0.x d.p0.y)
 ,,if(&rect) rect.left=d.p0.x; rect.top=d.p0.y; rect.right=rect.left; rect.bottom=rect.top; OffsetRect &rect d.xs d.ys
 ,else if(d.bmc.bm)
 ,,R=1
 ,,if(!empty(bmpfile)) R=SaveBitmap(d.bmc.bm bmpfile); if(!R) &result=0
 ,,if(&result) result=d.bmc.Detach
 ,,if(&rect) rect=d.r; OffsetRect &rect d.xs d.ys
 ,case 3 ;;Take another snapshot
 ,d.bmc.Delete; d.erase=0; d.retry=1
 ,TO_OsdTooltip "Press Shift when ready to take another snapshot.[][]Note: This is NOT a screen snapshot. You can rearrange windows, etc." -1 0 0 8
 ,;wait for Shift
 ,for(i 0 1000000)
 ,,0.003; ifk(S) break
 ,,if(i=20000) i=0; TO_OsdTooltip "Still waiting for Shift..." 0 0 0 0 0xff
 ,OsdHide; 0.1
 ,goto g1
 
 OsdHide
 if(hwndmin)
 ,if(flags&4) EnableWindow hwndmin 1
 ,if(flags&8=0 or !R)
 ,,if(min(ho)) res ho; act ho
 ,,act hwndmin
 
 0.01 ;;windows may be incorrectly ordered, eg like the max window is over taskbar
 ret R
 
 
 #sub Dlg
 function# hDlg message wParam lParam
 
 ___CIOC* d=+DT_GetParam(hDlg)
 POINT p; RECT r; int dc z
 sel message
 ,case WM_INITDIALOG
 ,MoveWindow hDlg d.xs d.ys d.cxs d.cys 0 ;;cover whole screen
 ,
 ,case WM_SHOWWINDOW ;;if on WM_INITDIALOG, hDlg may cover the tooltip
 ,if(wParam and d.flags&16=0) TO_OsdTooltip _s.from(iif(d.flags&1 "Click anywhere to pick the color." "Draw a rectangle with the mouse.") "[][]Note: This is a screen snapshot, not real windows.[]You can click anywhere to take another snapshot.") 10
 ,
 ,case WM_LBUTTONDOWN
 ,OsdHide
 ,xm d.p0 hDlg 1 ;;save mouse down coordinates
 ,SetCapture hDlg
 ,r.right=66; r.bottom=86; OffsetRect &r -d.xs+d.xmagn -d.ys; InvalidateRect hDlg &r 0 ;;erase magnifier
 ,
 ,case WM_MOUSEMOVE
 ,xm p hDlg 1
 ,dc=GetDC(hDlg)
 ,if(hDlg!=GetCapture) ;;draw magnifier/color
 ,,r.right=66; r.bottom=86; OffsetRect &r -d.xs+d.xmagn -d.ys ;;calc frame
 ,,if(PtInRect(&r p.x p.y)) d.xmagn=iif(d.xmagn 0 300); InvalidateRect hDlg &r 0; goto gr ;;move away
 ,,z=GetStockObject(BLACK_BRUSH); FrameRect dc &r z; r.top+65; FrameRect dc &r z ;;draw frames
 ,,StretchBlt(dc r.left+1 r.top-64 64 64 d.bms.dc p.x p.y 16 16 SRCCOPY) ;;draw magnifier
 ,,;draw color
 ,,_s.format("0x%06X" GetPixel(d.bms.dc p.x p.y))
 ,,InflateRect &r -1 -1; FillRect dc &r 1+COLOR_WINDOW; r.left+2; r.top+2
 ,,z=SelectObject(dc _hfont); DrawTextW dc @_s -1 &r 0; SelectObject(dc z)
 ,else if(d.flags&1=0) ;;draw focus rect
 ,,if(d.erase) DrawFocusRect dc &d.r; d.erase=0 ;;erase prev
 ,,SetRect &d.r iif(p.x>=d.p0.x d.p0.x p.x) iif(p.y>=d.p0.y d.p0.y p.y) iif(p.x<d.p0.x d.p0.x p.x) iif(p.y<d.p0.y d.p0.y p.y) ;;calc new
 ,,d.erase=DrawFocusRect(dc &d.r) ;;draw new
 ,;gr
 ,ReleaseDC hDlg dc
 ,
 ,case WM_LBUTTONUP
 ,if(hDlg!=GetCapture) ret
 ,ReleaseCapture
 ,_s="OK[]Cancel[]Take another snapshot[]Retry in current snapshot"
 ,if(d.flags&1=0)
 ,,if(d.erase and !IsRectEmpty(&d.r)) d.bmc.Create(d.r.right-d.r.left d.r.bottom-d.r.top d.bms.dc d.r.left d.r.top) ;;capture and save the rectangle
 ,,else _s.get(_s 4); _i=1 ;;remove OK from the menu
 ,if(d.flags&32) DT_Ok hDlg; ret
 ,d.inmenu=1
 ,z=ShowMenu(_s hDlg 0 2)
 ,d.inmenu=0
 ,if(!z) ret
 ,sel z+_i
 ,,case 1 DT_Ok hDlg
 ,,case 2 DT_Cancel hDlg
 ,,case 3 DT_Ok hDlg 3
 ,,
 ,case WM_PAINT
 ,PAINTSTRUCT ps
 ,dc=BeginPaint(hDlg &ps)
 ,if(!dc) end "BeginPaint" 17
 ,_i=BitBlt(dc 0 0 d.cxs d.cys d.bms.dc 0 0 SRCCOPY) ;;draw whole screen in hDlg
 ,if(!_i) end "BitBlt" 17
 ,EndPaint hDlg &ps
 ,ret 1
 ,
 ,case WM_COMMAND ret 1
 ,
 ,case WM_SETCURSOR
 ,if(d.inmenu) ret
 ,SetCursor TO_LoadCursor(4)
 ,ret 1
 
 ;BEGIN DIALOG
 ;0 "" 0x90000248 0x88 0 0 227 151 "Dialog"
 ;END DIALOG
 ;DIALOG EDITOR: "" 0x2020100 "" ""
Member function __MemBmp.Create_debug function width height [srcdc] [srcx] [srcy]
 ;Creates memory DC (device context), creates/selects bitmap, and optionally copies bitmap bits from other DC.
 
 ;width, height - bitmap width and height.
 ;srcdc - a DC from which to copy bitmap bits into this DC. Can be 0.
 ;;;If srcdc is 1 or 2, copies from screen.
 ;;;If it is 1, interprets srcx and srcy as coordinates in primary monitor.
 ;;;If it is 2, interprets srcx and srcy as coordinates in virtual screen (see GetVirtualScreen).
 ;srcx, srcx - offset in source DC from where to copy bits.
 
 
 Delete
 
 int dcs=GetDC(0)
 if(!dcs) end "GetDC" 17
 dc=CreateCompatibleDC(0)
 if(!dc) end "CreateCompatibleDC" 17
 bm=CreateCompatibleBitmap(dcs width height)
 if(!bm) end "CreateCompatibleBitmap" 17
 oldbm=SelectObject(dc bm)
 if(!oldbm) end "CreateCompatibleBitmap" 17
 
 if(srcdc)
 ,if(srcdc=2) srcdc=1; int x y; GetVirtualScreen x y; srcx+x; srcy+y
 ,_i=BitBlt(dc 0 0 width height iif(srcdc=1 dcs srcdc) srcx srcy SRCCOPY)
 ,if(!_i) end "BitBlt" 17
 
 ReleaseDC(0 dcs)
 
	
	
	
		
	Posts: 1,058Threads: 367
 Joined: Oct 2007
 
	
	
		Dear Gintaras, 
Many thanks, as always. I get the following error :
 
Error (RT) in <open ":3026: /724">__MemBmp.Create_debug:  CreateCompatibleBitmap. Not enough storage is available to process this command. (0x8).    <help #IDP_ERR>?
 
in __MemBmp.Create_debug following lines :
 
Member function __MemBmp.Create_debug bm=CreateCompatibleBitmap(dcs width height)if(!bm) end "CreateCompatibleBitmap" 17
Could you please advise?
	 
	
	
	
		
	Posts: 12,239Threads: 144
 Joined: Dec 2002
 
	
	
		What are width and height values?
	 
	
	
	
		
	Posts: 1,058Threads: 367
 Joined: Oct 2007
 
	
	
	
		
	Posts: 12,239Threads: 144
 Joined: Dec 2002
 
	
	
		Fails to allocate 9 MB of memory. Something wrong with memory, normally should allocate hundreds MB. 
Try to call CreateCompatibleBitmap repeatedly until succeeds.
 
Macro Macro2369 rep 100 ;;wait max 10s,bm=CreateCompatibleBitmap(dcs width height)
 ,if(bm) break
 ,0.1
 if(!bm) end "CreateCompatibleBitmap" 17
 
	
	
	
		
	Posts: 1,058Threads: 367
 Joined: Oct 2007
 
	
	
		I tried it. It looped 100 times, but no success.
	 
	
	
	
		
	Posts: 12,239Threads: 144
 Joined: Dec 2002
 
	
	
		I googled forCreateCompatibleBitmap error 8
 Found many results with this problem, but did not find a solution or a reason explained. From what I found, it usually happens only on some (rare) computers, when creating large bitmaps. But we cannot create a smaller bitmap if need whole screen to select from. It seems that in some rare cases CreateCompatibleBitmap uses video memory and then the bitmap size is limited. Also found that it happens more often if there are more applications running, eg multiple Internet Explorer pages. I guess maybe then Windows limits the amount of memory available for each application.
 
	
	
	
		
	Posts: 1,058Threads: 367
 Joined: Oct 2007
 
	
	
		Many thanks. However, let me ask a short question : although I select with mouse a small portion of the screen, variables width and height report the resolution of the whole screen in pixels. I wonder whether this is reasonable.
 Best Regards.
 |