打开画图工具后,执行ctrl+v,提示“剪贴板上的信息无法插入画图”
在VFP9表单的command控件click事件里写如下代码,提示“截图已旋转成功并写回剪贴板”,但打开画图工具后,执行ctrl+v,提示“剪贴板上的信息无法插入画图”
LOCAL nGdiplusToken, hImage, nStatus, oClipboard
LOCAL Rotate180FlipNone, GP_OK, GDIP_S_OK
LOCAL lcGdiplusInput, nVersion
* -------------------------- 1. 修正API声明和常量 --------------------------
* GDI+初始化/终止函数(补充结构体参数的正确定义)
DECLARE INTEGER GdiplusStartup IN gdiplus;
INTEGER @token, STRING @input, STRING @output
DECLARE INTEGER GdiplusShutdown IN gdiplus INTEGER token
* 图像旋转函数
DECLARE INTEGER GdipImageRotateFlip IN gdiplus;
INTEGER hImage, INTEGER rfType
* 剪贴板/位图相关API
DECLARE INTEGER OpenClipboard IN user32 INTEGER hwnd
DECLARE INTEGER GetClipboardData IN user32 INTEGER uFormat
DECLARE INTEGER CloseClipboard IN user32
DECLARE INTEGER DeleteObject IN gdi32 INTEGER hObject
DECLARE INTEGER EmptyClipboard IN user32
DECLARE INTEGER SetClipboardData IN user32 INTEGER uFormat, INTEGER hMem
* GDI+位图转换API
DECLARE INTEGER GdipCreateBitmapFromHBITMAP IN gdiplus;
INTEGER hBitmap, INTEGER hPalette, INTEGER @hImage
DECLARE INTEGER GdipDisposeImage IN gdiplus INTEGER hImage
DECLARE INTEGER GdipCreateHBITMAPFromBitmap IN gdiplus;
INTEGER hImage, INTEGER @hBitmap, INTEGER BackgroundColor
* 常量定义
#DEFINE CF_BITMAP 2
&& 剪贴板位图格式
#DEFINE GDIP_S_OK 0
&& GDI+操作成功返回值
Rotate180FlipNone = 2
&& 旋转180度不翻转
* -------------------------- 2. 正确初始化GdiplusStartupInput结构体 --------------------------
* GdiplusStartupInput结构体结构(共16字节):
* 偏移0-3:GdiplusVersion(UINT32,必须=1)
* 偏移4-7:DebugEventCallback(DWORD,=0)
* 偏移8-11:SuppressBackgroundThread(BOOL,=0)
* 偏移12-15:SuppressExternalCodecs(BOOL,=0)
nVersion = 1
lcGdiplusInput = ;
BINTOC(nVersion, "4RS") + ;
&& 版本号设为1(4字节,小端序)
REPLICATE(CHR(0), 12)
&& 其余字段填0
nGdiplusToken = 0
nStatus = GdiplusStartup(@nGdiplusToken, @lcGdiplusInput, 0)
IF nStatus <> GDIP_S_OK
MESSAGEBOX("GDI+初始化失败!错误码:" + ALLTRIM(STR(nStatus)), 16, "错误")
* 额外排查:检查gdiplus.dll是否存在
IF !FILE("C:\Windows\SysWOW64\gdiplus.dll") AND !FILE("C:\Windows\System32\gdiplus.dll")
MESSAGEBOX("未找到gdiplus.dll!请确认系统已安装GDI+组件", 16, "提示")
ENDIF
RETURN
ENDIF
* -------------------------- 3. 读取剪贴板中的截图 --------------------------
hImage = 0
hBitmap = 0
IF OpenClipboard(Thisform.HWnd) = 1
hBitmap = GetClipboardData(CF_BITMAP)
IF hBitmap <> 0
nStatus = GdipCreateBitmapFromHBITMAP(hBitmap, 0, @hImage)
IF nStatus <> GDIP_S_OK
MESSAGEBOX("剪贴板无有效截图!错误码:" + ALLTRIM(STR(nStatus)), 16, "提示")
CloseClipboard()
GdiplusShutdown(nGdiplusToken)
RETURN
ENDIF
ELSE
MESSAGEBOX("剪贴板无位图数据!", 16, "提示")
CloseClipboard()
GdiplusShutdown(nGdiplusToken)
RETURN
ENDIF
CloseClipboard()
ELSE
MESSAGEBOX("无法打开剪贴板!", 16, "错误")
GdiplusShutdown(nGdiplusToken)
RETURN
ENDIF
* -------------------------- 4. 执行180度旋转 --------------------------
nStatus = GdipImageRotateFlip(hImage, Rotate180FlipNone)
IF nStatus <> GDIP_S_OK
MESSAGEBOX("图像旋转失败!错误码:" + ALLTRIM(STR(nStatus)), 16, "错误")
GdipDisposeImage(hImage)
DeleteObject(hBitmap)
GdiplusShutdown(nGdiplusToken)
RETURN
ENDIF
* -------------------------- 5. 将旋转后的图像写回剪贴板 --------------------------
hNewBitmap = 0
nStatus = GdipCreateHBITMAPFromBitmap(hImage, @hNewBitmap, 0xFFFFFFFF)
&& 白色背景
IF nStatus = GDIP_S_OK
OpenClipboard(Thisform.HWnd)
EmptyClipboard()
SetClipboardData(CF_BITMAP, hNewBitmap)
CloseClipboard()
DeleteObject(hNewBitmap)
ENDIF
* -------------------------- 6. 释放资源 --------------------------
GdipDisposeImage(hImage)
DeleteObject(hBitmap)
GdiplusShutdown(nGdiplusToken)
MESSAGEBOX("截图已旋转180度并写回剪贴板!", 64, "成功")
以下是引用sych在2025-12-11 10:12:32的发言:
Public Declare Function GdipImageRotateFlip Lib "gdiplus" (ByVal Image As Long, ByVal rfType As RotateFlipType) As GpStatus
RotateNoneFlipNone = 0, // 不旋转不翻转
Rotate90FlipNone = 1, // 旋转90度不翻转
Rotate180FlipNone = 2, // 旋转180度不翻转
Rotate270FlipNone = 3, // 旋转270度不翻转
RotateNoneFlipX = 4, // 不旋转x向翻转
Rotate90FlipX = 5, // 旋转90度x向翻转
Rotate180FlipX = 6, // 旋转180度x向翻转
Rotate270FlipX = 7, // 旋转270度x向翻转
Declare Long GdipDrawImageRectI in GdiPlus.dll Long graphics, Long image, long x, long y, long width, long height
把原图变化到多大(后两个参数),复制到新图哪个位置(前两个参数)