Posts: 1,058
Threads: 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,066
Threads: 140
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,058
Threads: 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,066
Threads: 140
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 r
str 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,058
Threads: 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,058
Threads: 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,066
Threads: 140
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,058
Threads: 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,066
Threads: 140
Joined: Dec 2002
What are width and height values?
Posts: 1,058
Threads: 367
Joined: Oct 2007
Posts: 12,066
Threads: 140
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,058
Threads: 367
Joined: Oct 2007
I tried it. It looped 100 times, but no success.
Posts: 12,066
Threads: 140
Joined: Dec 2002
I googled for
CreateCompatibleBitmap 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,058
Threads: 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.
|