服务中调用BitBlt失败,为何???

lordharrt 2005-08-09 03:41:12
我写一个程序抓当前屏幕,放在dll中,用普通方法调用时没有问题,但是将调用dll的程序写成win32服务的形式时却失败,抓图代码如下,跟踪发现BitBlt时失败,GetLastError得到的是"句柄无效"请问如何解决?

HBITMAP CopyScreenToBitmap(LPRECT lpRect)

//lpRect 代表选定区域

{

HDC hScrDC = NULL;
HDC hMemDC = NULL;

// 屏幕和内存设备描述表
HGDIOBJ hBitmap = NULL;
HGDIOBJ hOldBitmap = NULL;

// 位图句柄
int nX, nY, nX2, nY2;

// 选定区域坐标
int nWidth, nHeight;

// 位图宽度和高度
int xScrn, yScrn;

// 确保选定区域不为空矩形

if (IsRectEmpty(lpRect))

return NULL;

//为屏幕创建设备描述表

hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL);

//为屏幕设备描述表创建兼容的内存设备描述表

hMemDC = CreateCompatibleDC(hScrDC);

// 获得选定区域坐标
nX = lpRect->left;
nY = lpRect->top;
nX2 = lpRect->right;
nY2 = lpRect->bottom;

// 获得屏幕分辨率
xScrn = GetDeviceCaps(hScrDC, HORZRES);

yScrn = GetDeviceCaps(hScrDC, VERTRES);

//确保选定区域是可见的

if (nX < 0)
nX = 0;
if (nY < 0)
nY = 0;
if (nX2 > xScrn)
nX2 = xScrn;
if (nY2 > yScrn)
nY2 = yScrn;

nWidth = nX2 - nX;
nHeight = nY2 - nY;

// 创建一个与屏幕设备描述表兼容的位图

hBitmap = CreateCompatibleBitmap

(hScrDC, nWidth, nHeight);

// 把新位图选到内存设备描述表中

hOldBitmap = SelectObject(hMemDC, hBitmap);
DebugIntStr((int)hOldBitmap, "hOldBitmap....");

// 把屏幕设备描述表拷贝到内存设备描述表中
DebugIntStr((int)hMemDC, "hMemDC....");
DebugIntStr((int)hScrDC, "hScrDC....");

BitBlt(hMemDC, 0, 0, nWidth, nHeight,

hScrDC, nX, nY, SRCCOPY); //这里失败

//得到屏幕位图的句柄

hBitmap = SelectObject(hMemDC, hOldBitmap);

//清除

DeleteDC(hScrDC);

DeleteDC(hMemDC);

// 返回位图句柄
return (HBITMAP)hBitmap;
}
...全文
376 7 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
lordharrt 2005-08-09
  • 打赏
  • 举报
回复
成功了,
非常感谢idAnts(你才无聊呢),还有各位热心的朋友
teli_eurydice 2005-08-09
  • 打赏
  • 举报
回复
回复人: dirdirdir3(风) ( ) 信誉:100 2005-08-09 16:03:00 得分: 0


服务使用窗口类要经过特殊处理。


idAnts 2005-08-09
  • 打赏
  • 举报
回复
MSDN里有个服务程序使用MessageBox的例子,当然这个例子并不是为了解决使用MessageBox,服务程序中MessageBox使用MB_SERVICE_NOTIFICATION参数就可以用了。这个例子演示了和桌面交互。

DWORD dwGuiThreadId = 0;

int
UserMessageBox(
RPC_BINDING_HANDLE h,
LPSTR lpszWindowStation,
LPSTR lpszDesktop,
LPSTR lpszText,
LPSTR lpszTitle,
UINT fuStyle)
{
DWORD dwThreadId;
HWINSTA hwinstaSave;
HDESK hdeskSave;
HWINSTA hwinstaUser;
HDESK hdeskUser;
int result;

// Ensure connection to service window station and desktop, and
// save their handles.

GetDesktopWindow();
hwinstaSave = GetProcessWindowStation();
dwThreadId = GetCurrentThreadId();
hdeskSave = GetThreadDesktop(dwThreadId);

// Impersonate the client and connect to the User's
// window station and desktop.

RpcImpersonateClient(h);
hwinstaUser = OpenWindowStation(lpszWindowStation, FALSE, MAXIMUM_ALLOWED);
if (hwinstaUser == NULL)
{
RpcRevertToSelf();
return 0;
}
SetProcessWindowStation(hwinstaUser);
hdeskUser = OpenDesktop(lpszDesktop, 0, FALSE, MAXIMUM_ALLOWED);
RpcRevertToSelf();
if (hdeskUser == NULL)
{
SetProcessWindowStation(hwinstaSave);
CloseWindowStation(hwinstaUser);
return 0;
}
SetThreadDesktop(hdeskUser);

// Display message box.

dwGuiThreadId = dwThreadId;
result = MessageBox(NULL, lpszText, lpszTitle, fuStyle);
dwGuiThreadId = 0;

// Restore window station and desktop.

SetThreadDesktop(hdeskSave);
SetProcessWindowStation(hwinstaSave);
CloseDesktop(hdeskUser);
CloseWindowStation(hwinstaUser);

return result;
}

dirdirdir3 2005-08-09
  • 打赏
  • 举报
回复
服务使用窗口类要经过特殊处理。
lordharrt 2005-08-09
  • 打赏
  • 举报
回复
hScrDC 和hMemDC都是成功的
idAnts(你才无聊呢)能不能说详细点,如何设定WindowStation和Desktop? 解决马上结贴
idAnts 2005-08-09
  • 打赏
  • 举报
回复
服务程序和用户交互还要设定WindowStation和Desktop
DentistryDoctor 2005-08-09
  • 打赏
  • 举报
回复
是否成功的取得了HDC?

15,980

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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