PB 如何从粘贴板取图

fipamw 2010-01-17 12:48:30
我调用了一个QQ的截图OCX,该控件双击时会把图片复制到粘贴板上,但我想再把粘贴板的图片保存起来,该怎么做?

Function int CameraSubArea(int utype) LIBRARY "CameraDll.dll"
FUNCTION ulong GetClipboardData(ulong wFormat) LIBRARY "user32.dll"
FUNCTION ulong IsClipboardFormatAvailable(ulong wFormat) LIBRARY "user32.dll"
FUNCTION ulong GlobalLock(ulong hMem) LIBRARY "kernel32.dll"
FUNCTION ulong GlobalUnlock(ulong hMem) LIBRARY "kernel32.dll"
FUNCTION ulong GlobalSize(ulong hMem) LIBRARY "kernel32.dll"
subroutine copymemory(REF blob Destionation,blob Source, long length )library"kernel32.dll"
//subroutine copymemory(REF string Destionation,string Source, long length )library"kernel32.dll"
FUNCTION ulong OpenClipboard(ulong hwnd) LIBRARY "user32.dll"

li_return_msg =CameraSubArea(0)
IF li_return_msg = 1 THEN
if IsClipboardFormatAvailable(2) = 1 then
hGlobal = GetClipBoardData(2)
lp = GlobalLock(hGlobal)
//blobtemp = space(GlobalSize(lp))
//copymemory(ref blbResult,BlobTemp,lp)
GlobalUnlock(hGlobal)
in_bitmap.of_WriteBlob("c:\1.bmp", blob(blbResult))
end if
END IF


在网上找了这么一段,但就是报错,不行
请高手帮忙一下,谢谢
...全文
1791 21 打赏 收藏 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
xiaoyu1121 2011-12-31
  • 打赏
  • 举报
回复
还是没有实现~~~~~
yyoinge 2011-02-12
  • 打赏
  • 举报
回复
//lul_hBitmap由于已经通过selectobject函数选入上下文设备lul_hdcmem中,因此不需要再调用DeleteObject函数来删除

应该改为
DeleteObject(lul_hbitmap)
yyoinge 2011-02-12
  • 打赏
  • 举报
回复
借这个帖子说说PB截图的问题:
(1)PB按照屏幕像素截图,方法为:
BitBlt(lul_hdcMem, 0, 0, aul_width, aul_height, lul_hdc, aul_xpos, aul_ypos, SRCCOPY)
这种截图方法只能截取当前显示屏上的内容,超出部分截出来是黑色的
(2)按照窗口截图,方法为:
printwindow(awnd, lul_memdc, 0)
这种截图方法可以通过窗口的句柄进行截图,当窗口不是MDI子窗口时,可以截取被遮盖或者超出屏幕外的部分,但是当窗口为MDI子窗口时,无法截取超出MDI客户区的窗口部分。另外该函数只在XP及以上系统中可用
(3)发送消息截图,方法为:
constant long WM_PRINT = 791
constant long PRF_CHECKVISIBLE = 1
constant long PRF_NONCLIENT = 2
constant long PRF_CLIENT = 4
constant long PRF_ERASEBKGND = 8
constant long PRF_CHILDREN = 16
constant long PRF_OWNED = 32
send(awnd, WM_PRINT, lul_memdc,PRF_NONCLIENT + PRF_ERASEBKGND + PRF_CLIENT+ PRF_OWNED + PRF_CHILDREN)
这种方法可以按照控件或者窗口的句柄来截图,在任何情况下,被遮盖或者超出屏幕部分的窗口都可以被截到,但是对于不支持WM_PRINT消息的控件,改方法无法截取,datawindow控件就无法通过该方法截图。另外该方法截的窗口图中,各个控件的叠放顺序会发生改变(如:statictext控件总会被提到最前面)


这三种方法各有优缺点,但都还不是最好的,不知道大家还有没有什么更好的方法?
yyoinge 2011-02-12
  • 打赏
  • 举报
回复
//FUNCTION Boolean OpenClipboard(ULong hWndNewOwner) LIBRARY "user32.dll"
//FUNCTION Boolean CloseClipboard() LIBRARY "user32.dll"
//FUNCTION ULong GetClipboardData(ulong wFormat) LIBRARY "user32.dll"
//FUNCTION ulong IsClipboardFormatAvailable(ulong wFormat) LIBRARY "user32.dll"
//FUNCTION ULong GetDesktopWindow() LIBRARY "user32.dll"
//FUNCTION ULong GetDC(ULong hWnd) LIBRARY "user32.dll"
//FUNCTION ULong CreateCompatibleDC(ULong hdc) LIBRARY "gdi32.dll"
//FUNCTION ULong SelectObject(ULong hdc,ULong hgdiobj) LIBRARY "gdi32.dll"
//FUNCTION Int GetDIBits(ULong hdc,ULong hbmp,UInt uStartScan,UInt cScanLines,REF Blob lpvBits,REF bitmapinfo lpbi,UInt uUsage) LIBRARY "gdi32.dll"
//FUNCTION Int GetDIBits(ULong hdc,ULong hbmp,UInt uStartScan,UInt cScanLines, ULong lpvBits, REF bitmapinfo lpbi, UInt uUsage) LIBRARY "gdi32.dll"
//SUBROUTINE CopyBitmapFileHeader(REF Blob Destination, bitmapfileheader Source,Long Length) LIBRARY "kernel32.dll" ALIAS FOR "RtlMoveMemory"
//SUBROUTINE CopyBitmapInfo(REF Blob Destination, bitmapinfo Source,Long Length) LIBRARY "kernel32.dll" ALIAS FOR "RtlMoveMemory"
//FUNCTION Boolean DeleteDC(ULong hdc) LIBRARY "gdi32.dll"
//FUNCTION Int ReleaseDC(ULong hWnd,ULong hdc) LIBRARY "user32.dll"
//FUNCTION ULong CreateFile(String lpFileName, ULong dwDesiredAccess, ULong dwShareMode, ULong lpSecurityAttributes, ULong dwCreationDisposition, &
//ULong dwFlagsAndAttributes, ULong hTemplateFile ) LIBRARY "kernel32.dll" ALIAS FOR "CreateFileA"
//FUNCTION Boolean WriteFile(ULong hFile,Blob lpBuffer,ULong nNumberOfBytesToWrite,REF ULong lpNumberOfBytesWritten, &
//ULong lpOverlapped) LIBRARY "kernel32.dll"
//FUNCTION Boolean CloseHandle(ULong hObject) LIBRARY "kernel32.dll"
type bitmapfileheader from structure
integer bftype
long bfsize
integer bfreserved1
integer bfreserved2
long bfoffbits
end type

type bitmapinfoheader from structure
long bisize
long biwidth
long biheight
integer biplanes
integer bibitcount
long bicompression
long bisizeimage
long bixpelspermeter
long biypelspermeter
long biclrused
long biclrimportant
end type

type bitmapinfo from structure
bitmapinfoheader bmiheader
unsignedlong bmicolors[]
end type


//前面的是函数定义与结构体
long lul_hBitmap
ulong lul_hdcmem, hdc
//判断剪贴板中的数据是否是BMP数据
constant ulong CF_BITMAP = 2
if IsClipboardFormatAvailable(CF_BITMAP) = 1 then
//(1)开始从剪贴板取数据
OpenClipboard(GetDesktopWindow())
lul_hBitmap = GetClipBoardData(CF_BITMAP)
CloseClipboard()
blob lb
hdc = GetDC(GetDesktopWindow())
lul_hdcmem = CreateCompatibleDC(hdc)
selectobject(lul_hdcmem, lul_hBitmap)
//(2)将取得的内存图片转换位blob数据流
ULong lul_hdc, lul_pixels
Blob lblb_header, lblb_info, lblb_bitmap
BitmapInfo lstr_Info
BitmapFileHeader lstr_Header
IF lul_hBitmap <> 0 THEN
lstr_Info.bmiHeader.biSize = 40
IF GetDIBits(lul_hdcMem, lul_hBitmap, 0, 0, 0, lstr_Info, DIB_RGB_COLORS) > 0 THEN
lul_pixels = lstr_Info.bmiHeader.biBitCount
lstr_Info.bmiColors[lul_pixels] = 0
lblb_bitmap = Blob(Space(lstr_Info.bmiHeader.biSizeImage))
// 获取文件信息
GetDIBits(lul_hdcMem, lul_hBitmap, 0, lstr_Info.bmiHeader.biheight, &
lblb_bitmap, lstr_Info, DIB_RGB_COLORS)
// 创建BMP文件头
lstr_Header.bfType = BITMAPTYPE
lstr_Header.bfSize = lstr_Info.bmiHeader.biSizeImage
lstr_Header.bfOffBits = 54 + (lul_pixels * 4)
// 将文件头转换成blob
lblb_header = Blob(Space(14))
CopyBitmapFileHeader(lblb_header, lstr_Header, 14)
// 将文件内容转换为blob
lblb_info = Blob(Space(40 + lul_pixels * 4))
CopyBitmapInfo(lblb_info, lstr_Info, 40 + lul_pixels * 4)
// 整合文件信息
lblb_bitmap = lblb_header + lblb_info + lblb_bitmap
END IF
END IF
//释放通过GetDC或GetWindowDC所检索出来的公用上下文设备
ReleaseDC(GetDesktopWindow(),hdc)
//删除通过CreteDC或CreateCompatibleDC所创建的上下文设备
DeleteDC(lul_hdcmem)
//lul_hBitmap由于已经通过selectobject函数选入上下文设备lul_hdcmem中,因此不需要再调用DeleteObject函数来删除

//(3)取到图片文件后,则开始保存到文件中
if len(lblb_bitmap) > 0 then
CONSTANT ULong INVALID_HANDLE_VALUE = -1
CONSTANT ULong GENERIC_WRITE = 1073741824
CONSTANT ULong FILE_SHARE_WRITE = 2
CONSTANT ULong CREATE_ALWAYS = 2
ULong lul_file, lul_length, lul_written
Boolean lb_rtn
// (创建)打开文件
lul_file = CreateFile("d:\abc.bmp", GENERIC_WRITE, &
FILE_SHARE_WRITE, 0, CREATE_ALWAYS, 0, 0)
IF lul_file = INVALID_HANDLE_VALUE THEN
RETURN
END IF
// 写文件
lul_length = Len(lblb_bitmap)
lb_rtn = WriteFile(lul_file, lblb_bitmap, &
lul_length, lul_written, 0)
// 关闭文件
CloseHandle(lul_file)
end if
End If
JY创建美好 2011-01-19
  • 打赏
  • 举报
回复
关注,前几天正要搞这个,这两天又在忙别的,哪天也研究一下
shengli333 2010-12-24
  • 打赏
  • 举报
回复
我這里也有類似的問題,大家看來看看啊!
http://blog.csdn.net/shengli333/archive/2010/12/24/6096000.aspx
ahder 2010-03-20
  • 打赏
  • 举报
回复
学习 .
duzhy 2010-03-19
  • 打赏
  • 举报
回复
1楼说的程序非常强大,什么时候能写出这样的PB程序就可以了。
chennavy 2010-03-18
  • 打赏
  • 举报
回复
标记下,下载来学习一下2010年3月18日 23时16分06秒
hblwd 2010-01-30
  • 打赏
  • 举报
回复
1楼里就有答案,貌似还是进口的,楼主用心就可以完美解决。
fjfzyufan 2010-01-19
  • 打赏
  • 举报
回复
FUNCTION ulong GetClipboardData(ulong wFormat) LIBRARY "user32.dll"
FUNCTION ulong IsClipboardFormatAvailable(ulong wFormat) LIBRARY "user32.dll"
Function long CloseClipboard() Library "user32"
FUNCTION ulong OpenClipboard(ulong hwnd) LIBRARY "user32.dll"
Function ulong CopyImage (ulong handle,long un1,long n1, long n2,long un2) LIBRARY "user32.dll"

ulong hglobal,ll_hbitmap
if IsClipboardFormatAvailable(2) = 1 then
OpenClipboard(handle(parent))
hGlobal = GetClipBoardData(2)
CloseClipboard();
ll_hbitmap = copyimage(hglobal,0,0,0,4)
End If
ll_hbitmap 就是内存图片
但是要将内存图片存入文件就麻烦了

将HBITMAP句柄保存为本地bmp位图的链接:
(VC源代码)
http://blog.csdn.net/ok208043624/archive/2008/10/27/3151822.aspx
fipamw 2010-01-18
  • 打赏
  • 举报
回复
能不能贴出具体的代码,谢谢
fjfzyufan 2010-01-18
  • 打赏
  • 举报
回复
试了, 确实不行.
这个方法是拷贝字符串的.
用这个方法拷贝图片非常麻烦.
要用copyimage 拷贝为内存图片,
然后将内存图片再保存为文件.
fipamw 2010-01-18
  • 打赏
  • 举报
回复
hGlobal = OpenClipboard(Handle(Parent))
hGlobal = GetClipBoardData(1)
lp = GlobalLock(hGlobal)
li_count = GlobalSize(lp)
MemoryCopy(ls_a,lp,li_count)
GlobalUnlock(hGlobal)
CloseClipboard()

如果是以上代码,就没问题,ls_a就是粘贴板的文字
但如果是GetClipBoardData(2),改成取图片的,GlobalLock却返回0,不知道为什么
fipamw 2010-01-18
  • 打赏
  • 举报
回复
这样报错呀,有没有人真正实验过的呀,指教一下,急呀
fjfzyufan 2010-01-18
  • 打赏
  • 举报
回复
你给的例子应该行的吧

blob blobtemp
if IsClipboardFormatAvailable(2) = 1 then
hGlobal = GetClipBoardData(2)
lp = GlobalLock(hGlobal)
blobtemp = space(GlobalSize(lp))
copymemory(ref blbResult,BlobTemp,lp)
GlobalUnlock(hGlobal)
end if
这个时候 blobtemp 中存的就是BMP图片的内窜
你可以将picture控件看一下
picture.SetPicture(blobtemp)
应该能显示出图片来

剩下的就是将Blobtemp中的内容保存到文件就行了.
fipamw 2010-01-18
  • 打赏
  • 举报
回复
哪位高手请教一下
fipamw 2010-01-17
  • 打赏
  • 举报
回复
这个我下了,不好用。不是截整个屏幕,是自定义屏幕。
QQ有个控件能实现,就像QQ截屏一样,很好用。
但QQ截屏后是保存到粘贴板的,我要再把粘贴板的数据保存成图片。
就是不知道怎么保存,在网上找了很久都找不到

请高手们指教一下,谢谢
jlwei888 2010-01-17
  • 打赏
  • 举报
回复
http://download.csdn.net/source/1626134

681

社区成员

发帖
与我相关
我的任务
社区描述
PowerBuilder API 调用
社区管理员
  • API 调用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧