Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
CaptureImageOrColor Enquiry
#1
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.
#2
What is your CaptureImageOrColor calling code?
Does it happen when you capture image with dialog 'Find image'? It uses CaptureImageOrColor.
#3
This is my rather very simple calling code :

Function CaptureImage
Trigger CWci     Help - how to add the trigger to the macro
Code:
Copy      Help
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
#4
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     Help - how to add the trigger to the macro
Code:
Copy      Help
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
#5
Dear Gintaras,

Many thanks for your helpful advice. I will follow it, I am sure it will solve this problem. Kind regards, Simos.
#6
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.
#7
This is a debug version. If some API function fails, shows error there.

Function CaptureImageOrColor_debug
Code:
Copy      Help
;/
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
Code:
Copy      Help
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)
#8
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
Code:
Copy      Help
bm=CreateCompatibleBitmap(dcs width height)
if(!bm) end "CreateCompatibleBitmap" 17

Could you please advise?
#9
What are width and height values?
#10
1920 - 1200
#11
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
Code:
Copy      Help
rep 100 ;;wait max 10s
,bm=CreateCompatibleBitmap(dcs width height)
,if(bm) break
,0.1
if(!bm) end "CreateCompatibleBitmap" 17
#12
I tried it. It looped 100 times, but no success.
#13
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.
#14
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.


Forum Jump:


Users browsing this thread: 1 Guest(s)