服务中调用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;
}
...全文
134 点赞 收藏 7
写回复
7 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
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?
回复
相关推荐
发帖
界面
创建于2007-09-28

1.5w+

社区成员

VC/MFC 界面
申请成为版主
帖子事件
创建了帖子
2005-08-09 03:41
社区公告
暂无公告