请问c中如何实现截取屏幕的功能呢?先谢谢您了!顺问GetModuleFileName()用法。

wangjunandy 2004-08-09 03:17:30
请问c中该如何实现截取屏幕的功能呢?
希望您能给出实现其功能的思路或者关键代码,先谢谢您了!


还有,能解释一下 GetModuleFileName()这个方法的用法吗?该方法的参数如下:

DWORD GetModuleFileName(
HMODULE hModule, /* handle to module to find filename for */
LPTSTR lpFilename, /* pointer to buffer for module path */
DWORD nSize /* size of buffer, in characters */
);

我查了一下BCB的帮助,可是还是不明白具体的用法。按BCB的说明:当第一个参数为NULL时,其返回值是“the path for the file used to create the calling process”,希望您能给出一个具体的实例解释一下参数为NULL时的用法,谢谢!
...全文
245 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
wangjunandy 2004-08-09
  • 打赏
  • 举报
回复
呵呵,
我没用MFC,我的环境是BCB和DEV-C++
不过都一样,我主要是为了弄明白GetModuleFileName()的用法。
  • 打赏
  • 举报
回复
只要你的程序是MFC的程序,AfxGetInstanceHandle()就肯定可以使用,如果不是MFC程序,那么WinMain有一个参数就是hInstance,作用是一样的。不管用哪个方法得到全路径,都可以使用strrchr函数搜索最后边的'\\'来获得路径。也可以使用_splitpath获得路径。
  • 打赏
  • 举报
回复
按照下列步骤实现一个例子程序。运行此例子程序,选择菜单 Applications,从下拉菜单中选择菜单项 Executable File Name,将弹出一个对话框,显示当前正在运行的可执行文件的全路径名。

  实现例子程序的具体步骤如下:
  1.在 Visual C++ 中,利用 AppWizard 创建新的项目文件,并命名此项目文件为 LD34.MAK.
  2.在 Appstudio 的主菜单中添加新的菜单 Applications,在菜单 Applications 中添加新的菜单项 Executable File Name,ID 命名为 ID_EXE_FILE_NAME。
  3.在 ClassWizard 中.从下拉列表中选择对象 CMainFrame,从对象列表中选择 ID_EXE_FILE_NAME,选择消息 COMMAND,点击按钮 Add Function,在方法 OnExeFileName 中输入下列代码:


void CMainFrame::OnExeFileName()
{
char fileName[_MAX_PATH];

GetModuleFileName(AfxGetInstanceHandle(),fileName,_MAX_PATH);
MessageBox(fileName,"Executable File Name",MB_APPLMODAL|MB_OK);
}

  4.编译并运行此例子程序。
  • 打赏
  • 举报
回复
同一个应用程序由不同的用户使用时,应用程序的名字可能不同。有时需要找出应用程序实际使用的名字,以便于找到其所在的目录,也可根据实际名字显示版本信息.
Windows API 函数 GetModuleFileName 返回执行文件名,执行文件由应用程序的实例句柄确定。Windows API 函数 GetModuleFileName 有三个参数,第一个参数是可执行程序的实例句柄,在 Visual C++ 中,应用程序的实例句柄由函数 AfxGetInstanceHandle 取回。第二和第三个参数说明缓冲区和缓冲区的大小,缓冲区用来存放取回的文件名,缓冲区的大小用字节表示。
  一旦函数返回,消息框将弹出,显示缓冲区中的内容。应该注意,当 Windows 9x 应用程序运行在长文件名系统上时,可能会返回长文件名,因此使用缓冲区存放文件名前应该检查文件系统中是否有长文件名。
wangjunandy 2004-08-09
  • 打赏
  • 举报
回复
To:BroncoSpeedCoursing
谢谢您给出了这么详细的解答!
wangjunandy 2004-08-09
  • 打赏
  • 举报
回复
To:peter9606
告知windows或者linux任一平台下的实现方法都可以
那tc下应该如何实现呢?
  • 打赏
  • 举报
回复
下面用VC来逐步介绍实现过程.首先我们要确定屏幕截取的区域,用LPRECT结构来定义。可以截取一个窗口,或整个屏幕。以下代码把选定的屏幕区域拷贝到位图中。
  HBITMAP CopyScreenToBitmap(LPRECT lpRect)
   //lpRect 代表选定区域
  {
  HDC hScrDC, hMemDC;
   // 屏幕和内存设备描述表
  HBITMAP hBitmap, hOldBitmap;
   // 位图句柄
  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);
  // 把屏幕设备描述表拷贝到内存设备描述表中
  BitBlt(hMemDC, 0, 0, nWidth, nHeight,
  hScrDC, nX, nY, SRCCOPY);
  //得到屏幕位图的句柄
  hBitmap = SelectObject(hMemDC, hOldBitmap);
  //清除
  DeleteDC(hScrDC);
  DeleteDC(hMemDC);
  // 返回位图句柄
   return hBitmap;
  }
  得到屏幕位图句柄以后,我们可以把屏幕内容粘贴到剪贴板上。
  if (OpenClipboard(hWnd))
  //hWnd为程序窗口句柄
  {
  //清空剪贴板
  EmptyClipboard();
  //把屏幕内容粘贴到剪贴板上,hBitmap 为刚才的屏幕位图句柄
  SetClipboardData(CF_BITMAP, hBitmap);
  //关闭剪贴板
  CloseClipboard();
  }
  我们也可以把屏幕内容以位图格式存到磁盘文件上。
  int SaveBitmapToFile(HBITMAP hBitmap ,
  LPSTR lpFileName) //hBitmap 为刚才的屏幕位图句柄
  {
   //lpFileName 为位图文件名
  HDC hDC;
  //设备描述表
  int iBits;
  //当前显示分辨率下每个像素所占字节数
  WORD wBitCount;
  //位图中每个像素所占字节数
  //定义调色板大小, 位图中像素字节大小,位图文件大小 , 写入文件字节数
  DWORD dwPaletteSize=0,
  dwBmBitsSize,
  dwDIBSize, dwWritten;
  BITMAP Bitmap;
  //位图属性结构
  BITMAPFILEHEADER bmfHdr;
  //位图文件头结构
  BITMAPINFOHEADER bi;
  //位图信息头结构
  LPBITMAPINFOHEADER lpbi;
  //指向位图信息头结构
  HANDLE fh, hDib, hPal,hOldPal=NULL;
  //定义文件,分配内存句柄,调色板句柄 //计算位图文件每个像素所占字节数
  hDC = CreateDC(“DISPLAY",NULL,NULL,NULL);
  iBits = GetDeviceCaps(hDC, BITSPIXEL) *
  GetDeviceCaps(hDC, PLANES);
  DeleteDC(hDC);
  if (iBits < = 1)
  wBitCount = 1;
  else if (iBits < = 4)
  wBitCount = 4;
  else if (iBits < = 8)
  wBitCount = 8;
  else if (iBits < = 24)
  wBitCount = 24;
  //计算调色板大小
  if (wBitCount < = 8)
  dwPaletteSize = (1 < < wBitCount) *
  sizeof(RGBQUAD);
  //设置位图信息头结构
  GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap);
   bi.biSize = sizeof(BITMAPINFOHEADER);
  bi.biWidth = Bitmap.bmWidth;
  bi.biHeight = Bitmap.bmHeight;
  bi.biPlanes = 1;
  bi.biBitCount = wBitCount;
  bi.biCompression = BI_RGB;
  bi.biSizeImage = 0;
  bi.biXPelsPerMeter = 0;
  bi.biYPelsPerMeter = 0;
  bi.biClrUsed = 0;
  bi.biClrImportant = 0;
  dwBmBitsSize = ((Bitmap.bmWidth *
  wBitCount+31)/32)* 4
   Bitmap.bmHeight ;
   //为位图内容分配内存
   hDib = GlobalAlloc(GHND,dwBmBitsSize+
  dwPaletteSize+sizeof(BITMAPINFOHEADER));
  lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
  *lpbi = bi;
  // 处理调色板
  hPal = GetStockObject(DEFAULT_PALETTE);
  if (hPal)
  {
   hDC = GetDC(NULL);
  hOldPal = SelectPalette(hDC, hPal, FALSE);
  RealizePalette(hDC);
  }
  // 获取该调色板下新的像素值
  GetDIBits(hDC, hBitmap, 0, (UINT) Bitmap.bmHeight,
   (LPSTR)lpbi + sizeof
  (BITMAPINFOHEADER)
  +dwPaletteSize,
  (BITMAPINFOHEADER *)
  lpbi, DIB_RGB_COLORS);
  //恢复调色板
  if (hOldPal)
  {
  SelectPalette(hDC, hOldPal, TRUE);
  RealizePalette(hDC);
  ReleaseDC(NULL, hDC);
  }
  //创建位图文件
  fh = CreateFile(lpFileName, GENERIC_WRITE,
  0, NULL, CREATE_ALWAYS,
  FILE_ATTRIBUTE_NORMAL | FILE_
  FLAG_SEQUENTIAL_SCAN, NULL);
  if (fh == INVALID_HANDLE_VALUE)
  return FALSE;
  // 设置位图文件头
  bmfHdr.bfType = 0x4D42; // "BM"
  dwDIBSize = sizeof(BITMAPFILEHEADER)
  + sizeof(BITMAPINFOHEADER)
  + dwPaletteSize + dwBmBitsSize;
  bmfHdr.bfSize = dwDIBSize;
  bmfHdr.bfReserved1 = 0;
  bmfHdr.bfReserved2 = 0;
  bmfHdr.bfOffBits = (DWORD)sizeof
  (BITMAPFILEHEADER)
  + (DWORD)sizeof(BITMAPINFOHEADER)
  + dwPaletteSize;
  // 写入位图文件头
  WriteFile(fh, (LPSTR)&bmfHdr, sizeof
  (BITMAPFILEHEADER), &dwWritten, NULL);
  // 写入位图文件其余内容
  WriteFile(fh, (LPSTR)lpbi, dwDIBSize,
  &dwWritten, NULL);
  //清除
  GlobalUnlock(hDib);
  GlobalFree(hDib);
  CloseHandle(fh);}


peter9606 2004-08-09
  • 打赏
  • 举报
回复
看你用什么开发工具在什么平台下开发了

c本身没有这样的函数
tc下倒是有获得当前视口的方法

70,037

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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