李文 发表于 2006-7-12 15:08:06

在WR中调用DLL 截屏函数的问题

用VC弄了个关于截屏的Dll程序,但是在WR中运行时总是跑不通,希望高手指点,具体代码如下:
// CutScreenDll.cpp : Defines the initialization routines for the DLL.
//

#include "stdafx.h"
#include <afxdllx.h>
#include<iostream>
#include <string>
using namespace std;

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


static AFX_EXTENSION_MODULE CutScreenDllDLL = { NULL, NULL };

extern "C" int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
        // Remove this if you use lpReserved
        UNREFERENCED_PARAMETER(lpReserved);

        if (dwReason == DLL_PROCESS_ATTACH)
        {
                TRACE0("CUTSCREENDLL.DLL Initializing!\n");
               
                // Extension DLL one-time initialization
                if (!AfxInitExtensionModule(CutScreenDllDLL, hInstance))
                        return 0;

                // Insert this DLL into the resource chain
                // NOTE: If this Extension DLL is being implicitly linked to by
                //an MFC Regular DLL (such as an ActiveX Control)
                //instead of an MFC application, then you will want to
                //remove this line from DllMain and put it in a separate
                //function exported from this Extension DLL.The Regular DLL
                //that uses this Extension DLL should then explicitly call that
                //function to initialize this Extension DLL.Otherwise,
                //the CDynLinkLibrary object will not be attached to the
                //Regular DLL's resource chain, and serious problems will
                //result.

                new CDynLinkLibrary(CutScreenDllDLL);
        }
        else if (dwReason == DLL_PROCESS_DETACH)
        {
                TRACE0("CUTSCREENDLL.DLL Terminating!\n");
                // Terminate the library before destructors are called
                AfxTermExtensionModule(CutScreenDllDLL);
        }
        return 1;   // ok
}


void Screen(char filename[])
{

CDC *pDC;//屏幕DC
pDC = CDC::FromHandle(GetDC(NULL));//获取当前整个屏幕DC
int BitPerPixel = pDC->GetDeviceCaps(BITSPIXEL);//获得颜色模式
int Width = pDC->GetDeviceCaps(HORZRES);
int Height = pDC->GetDeviceCaps(VERTRES);

cout << "当前屏幕色彩模式为" << BitPerPixel << "位色彩" << endl
<< "屏幕宽度:" << Width << endl
<< "屏幕高度:" << Height << endl << endl;

CDC memDC;//内存DC
memDC.CreateCompatibleDC(pDC);

CBitmap memBitmap, *oldmemBitmap;//建立和屏幕兼容的bitmap
memBitmap.CreateCompatibleBitmap(pDC, Width, Height);

oldmemBitmap = memDC.SelectObject(&memBitmap);//将memBitmap选入内存DC
memDC.BitBlt(0, 0, Width, Height, pDC, 0, 0, SRCCOPY);//复制屏幕图像到内存DC

//以下代码保存memDC中的位图到文件
BITMAP bmp;
memBitmap.GetBitmap(&bmp);//获得位图信息

FILE *fp = fopen(filename, "w+b");

BITMAPINFOHEADER bih = {0};//位图信息头
bih.biBitCount = bmp.bmBitsPixel;//每个像素字节大小
bih.biCompression = BI_RGB;
bih.biHeight = bmp.bmHeight;//高度
bih.biPlanes = 1;
bih.biSize = sizeof(BITMAPINFOHEADER);
bih.biSizeImage = bmp.bmWidthBytes * bmp.bmHeight;//图像数据大小
bih.biWidth = bmp.bmWidth;//宽度

BITMAPFILEHEADER bfh = {0};//位图文件头
bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);//到位图数据的偏移量
bfh.bfSize = bfh.bfOffBits + bmp.bmWidthBytes * bmp.bmHeight;//文件总的大小
bfh.bfType = (WORD)0x4d42;

fwrite(&bfh, 1, sizeof(BITMAPFILEHEADER), fp);//写入位图文件头

fwrite(&bih, 1, sizeof(BITMAPINFOHEADER), fp);//写入位图信息头

byte * p = new byte;//申请内存保存位图数据

GetDIBits(memDC.m_hDC, (HBITMAP) memBitmap.m_hObject, 0, Height, p,
(LPBITMAPINFO) &bih, DIB_RGB_COLORS);//获取位图数据

fwrite(p, 1, bmp.bmWidthBytes * bmp.bmHeight, fp);//写入位图数据

delete [] p;

fclose(fp);

memDC.SelectObject(oldmemBitmap);
}




wr中的代码
load_dll("E:\\VC\\CutScreenDll\\Debug\\CutScreenDll.dll");
filename="a";
extern int Screen(filename);#跑到这里出现如图所示提示框


Screen(filename);//调用Screen函数


unload_dll("E:\\VC\\CutScreenDll\\Debug\\CutScreenDll.dll");

G:\Snap3.bmp

李文 发表于 2006-7-13 14:31:26

各位啊,有知道的吗?这边着急啊

李文 发表于 2006-7-18 09:52:10

怎么还没有人回复啊,是不是我说的不清楚啊

guirongb 发表于 2006-7-18 11:10:18

一、
你的C++ 函数是void型的
你的Wr调用返回是Int型的

二、最好不要使用MFC的DLL方式写

三、不要传数组作为参数

还有这段代码不是楼主自己写的吧,肯定是哪儿Copy过来的,哈哈

guyu_susa 发表于 2006-7-18 11:36:43

报错的原因可能是函数定义错误,没有描述函数参数的类型

还有,dll里的相关函数要是int型的
同时对这种dll能否调用成功表示怀疑。

shyfish 发表于 2006-7-18 20:32:39

如果DLL没问题那把WR 的 extern函数改下:
extern extern int Screen(in string); // 如果不修改, 如果要输出, inout 代替 in
给个链接:
http://bbs.51testing.com/viewthread.php?tid=9375&highlight=shyfish

MFC写的DLL完全可用, 而且简单(导出函数使用引用都可以). 用作辅助WR很好啊

[ 本帖最后由 51Testing论坛 于 2008-4-22 23:08 编辑 ]

jbmw_dzg 发表于 2006-7-18 22:07:31

楼上的,再你的wr中重新声名你的函数 extern int Screen( in string filename);

jbmw_dzg 发表于 2006-7-18 22:11:44

另外,你的filename因该是个文件名吧,在WR不能像你那样调用
你应该这样
static filename;
filename="c:\1.bmp"
然后调用函数

李文 发表于 2006-7-20 11:27:39

谢谢大家啊 ,我先调试一下,要是好使这段代码大家就可以一起使用了啊

李文 发表于 2006-7-21 13:42:56

通过大家的帮助,代码这下子可以 用了sdlkfj2,
// CutScreenDll.cpp : Defines the initialization routines for the DLL.
//

#include "stdafx.h"
#include <afxdllx.h>
#include<iostream>
#include <string>
using namespace std;

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


static AFX_EXTENSION_MODULE CutScreenDllDLL = { NULL, NULL };

extern "C" int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
        // Remove this if you use lpReserved
        UNREFERENCED_PARAMETER(lpReserved);

        if (dwReason == DLL_PROCESS_ATTACH)
        {
                TRACE0("CUTSCREENDLL.DLL Initializing!\n");
               
                // Extension DLL one-time initialization
                if (!AfxInitExtensionModule(CutScreenDllDLL, hInstance))
                        return 0;

                // Insert this DLL into the resource chain
                // NOTE: If this Extension DLL is being implicitly linked to by
                //an MFC Regular DLL (such as an ActiveX Control)
                //instead of an MFC application, then you will want to
                //remove this line from DllMain and put it in a separate
                //function exported from this Extension DLL.The Regular DLL
                //that uses this Extension DLL should then explicitly call that
                //function to initialize this Extension DLL.Otherwise,
                //the CDynLinkLibrary object will not be attached to the
                //Regular DLL's resource chain, and serious problems will
                //result.

                new CDynLinkLibrary(CutScreenDllDLL);
        }
        else if (dwReason == DLL_PROCESS_DETACH)
        {
                TRACE0("CUTSCREENDLL.DLL Terminating!\n");
                // Terminate the library before destructors are called
                AfxTermExtensionModule(CutScreenDllDLL);
        }
        return 1;   // ok
}


extern"C" __declspec(dllexport) void Screen(char *filename)
{

CDC *pDC;//屏幕DC
pDC = CDC::FromHandle(GetDC(NULL));//获取当前整个屏幕DC
int BitPerPixel = pDC->GetDeviceCaps(BITSPIXEL);//获得颜色模式
int Width = pDC->GetDeviceCaps(HORZRES);
int Height = pDC->GetDeviceCaps(VERTRES);

CDC memDC;//内存DC
memDC.CreateCompatibleDC(pDC);

CBitmap memBitmap, *oldmemBitmap;//建立和屏幕兼容的bitmap
memBitmap.CreateCompatibleBitmap(pDC, Width, Height);

oldmemBitmap = memDC.SelectObject(&memBitmap);//将memBitmap选入内存DC
memDC.BitBlt(0, 0, Width, Height, pDC, 0, 0, SRCCOPY);//复制屏幕图像到内存DC

//以下代码保存memDC中的位图到文件
BITMAP bmp;
memBitmap.GetBitmap(&bmp);//获得位图信息

FILE *fp = fopen(filename, "w+b");

BITMAPINFOHEADER bih = {0};//位图信息头
bih.biBitCount = bmp.bmBitsPixel;//每个像素字节大小
bih.biCompression = BI_RGB;
bih.biHeight = bmp.bmHeight;//高度
bih.biPlanes = 1;
bih.biSize = sizeof(BITMAPINFOHEADER);
bih.biSizeImage = bmp.bmWidthBytes * bmp.bmHeight;//图像数据大小
bih.biWidth = bmp.bmWidth;//宽度

BITMAPFILEHEADER bfh = {0};//位图文件头
bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);//到位图数据的偏移量
bfh.bfSize = bfh.bfOffBits + bmp.bmWidthBytes * bmp.bmHeight;//文件总的大小
bfh.bfType = (WORD)0x4d42;

fwrite(&bfh, 1, sizeof(BITMAPFILEHEADER), fp);//写入位图文件头

fwrite(&bih, 1, sizeof(BITMAPINFOHEADER), fp);//写入位图信息头

byte * p = new byte;//申请内存保存位图数据

GetDIBits(memDC.m_hDC, (HBITMAP) memBitmap.m_hObject, 0, Height, p,
(LPBITMAPINFO) &bih, DIB_RGB_COLORS);//获取位图数据

fwrite(p, 1, bmp.bmWidthBytes * bmp.bmHeight, fp);//写入位图数据

delete [] p;

fclose(fp);

memDC.SelectObject(oldmemBitmap);

}


WR中的代码:
externint Screen(string filename);
load_dll("E:\\VC\\CutScreenDll\\Debug\\CutScreenDll.dll");
Screen("d:\\bmp.bmp");

unload_dll("E:\\VC\\CutScreenDll\\Debug\\CutScreenDll.dll");

byya 发表于 2008-3-21 16:47:29

我把DLL編譯了
看看能不能用

[ 本帖最后由 byya 于 2008-3-21 17:09 编辑 ]

byya 发表于 2008-3-21 16:53:31

的確可以用..不借..速度很快...這樣有錯誤時可以自動截圖...這功能好

shuishixingyu 发表于 2008-4-7 10:13:14

好东西

贝壳里的海 发表于 2009-11-23 15:28:11

我是自己录制了一个脚本,在测试软件的时候同时激活红蜻蜓抓图精灵,用这个软件的截屏功能来截屏

flying-kite 发表于 2010-11-9 13:01:26

有人提到: 为什么不用自带的WR函数win_capture_bitmap呢?
页: [1]
查看完整版本: 在WR中调用DLL 截屏函数的问题