返回首页


简介
有许多屏幕捕捉程序,但我不与他们最高兴的。所以我做了自己的屏幕捕捉程序。这项计划将不会为您提供的设施进行拍照ofnbsp;下拉菜单,此功能是特意排除。如果你想自己来实现它;你会发现在互联网上的足够的信息。此外,它涉及到另一个模块为DLL,我想保持它的简单。背景
完整的应用不仅是屏幕捕获,但像WTL,STL和其他科目。 使用代码
在CMainFrame窗口内有三个类:WindowInfo,CBorderWnd,并CClientView。
Windows有许多有趣的属性,但这个方案是只在三个感兴趣,标题的窗口,应用程序(或模块)的名称,以及应用程序的线程ID。应用程序不使用object-oriented/encapsulation指引,所以一切是公开的。
首先,你需要创建一个MDI应用程序与WTL的向导。

该向导将创建在MainForm的文件(头文件和CPP)的CMainFrame类。下面的类声明内为MainFrm.h:/ /类WindowInfo{市民: WindowInfo(TCHAR * pstrWindowTitle = NULL, TCHAR * pstrModuleName = NULL,DWORD dwPID = 0) {  0; memset的(m_strWindowTitle,0,_MAX_PATH);   ; memset的(m_strModuleName,0,_MAX_PATH);  60; (pstrWindowTitle!= NULL)   ; strcpy_s(m_strWindowTitle,pstrWindowTitle);  60; (pstrModuleName!= NULL) & #160; strcpy_s(m_strModuleName,pstrModuleName);  60; m_dwPID = dwPID; } TCHAR m_strWindowTitle [_MAX_PATH]; TCHAR m_strModuleName [_MAX_PATH]; DWORD m_dwPID;};/ /
类CBorderWnd是负责周围绘制另一个窗口的边框,只有WM_ERASEBKGND的处理/ /CBorderWnd类:公共CWindowImpllt; CBorderWndgt;{市民: BEGIN_MSG_MAP(CBorderWnd) MESSAGE_HANDLER(WM_ERASEBKGND,OnEraseBkgnd) END_MSG_MAP() LRESULT OnEraseBkgnd(UINT uMsg,WPARAM wParam参数, & #160; LPARAM lParam的,BOOLamp; bHandled) { RECT RECT; &# 160; GetClientRect(AMP; RECT); bHandled =; HDC的hDC =(HDC)wParam参数; &# 160; HPEN hRedPen =::CreatePen(PS_SOLID,16,RGB(255,0,0)); HPEN hOldPen =(HPEN):(HDC,hRedPen); HBRUSH hOldBrush =(HBRUSH)选择对象(HDC, (HBRUSH)GetStockObject(NULL_BRUSH)); 矩形(HDC,rect.left,rect.top,rect.right,rect.bottom); 选择对象:(HDC,hOldPen); 选择对象:(HDC,hOldBrush); DeleteObject(hRedPen);   ; 返回0; }};/ /
和CClientView会得出任何的MDI应用程序内的图片。/ /CClientView类:公共CWindowImpllt; CClientViewgt;{市民: HBITMAP m_bmSonyCamera; 尺寸m_size; BEGIN_MSG_MAP(CSlideView)  60; MESSAGE_HANDLER(WM_SIZE,OnSize) MESSAGE_HANDLER(WM_PAINT,OnPaint中)  60;MESSAGE_HANDLER(WM_CREATE,OnCreate中) END_MSG_MAP() LRESULT OnPaint中(UINT / * uMsg * /,WPARAM / * wParam参数* / LPARAM / * lParam参数* / BOOLamp; / * * / bHandled); LRESULT的OnCreate(UINT / * uMsg * /,WPARAM / * wParam参数* /, &# 160; LPARAM / * lParam参数* / BOOLamp; / * * / bHandled); LRESULT OnSize(UINT uMsg,WPARAM wParam参数, & #160; LPARAM lParam的,BOOLamp; bHandled);};/ /
当我们创建了一个新的关键字视图,WTL将删除该内存位置,不会有内存泄漏,但我们仍然要保持各方面的意见,每当我们创建它们的轨道。出于这个原因,vectorlt; CChildFrame * GT; m_bmList;包括在内。在创建视图之前,我们还需要HWND,WindowInfogt; m_HanldeList;用于保持对所有桌面Windows maplt的信息。还需要一个静态函数EnumDesktopWindows function.static BOOL CALLBACK EnumWindowsProc(HWND HWND,LPARAM lParam的);
此应用程序都有一个所有者绘制组合框,和所有者绘制代码,你可以创建一个字体,使用后删除的字体,但最好的方法来处理它是分配给对象(组合框的字体) :::SendMessage消息(m_hWndComboBox,(UINT)WM_SETFONT,(WPARAM)m_hFont,TRUE);
这样,你需要创建一个字体只有一次,并在退出时删除它。
正如你可以从图片中看到,组合框工具栏里面的,所以要修改的资源文件。根据在工具栏上的任何对象的大小,都需要许多分离器(8个像素)。在这种情况下,32分离器s者。现在,该组合框,并设置工具栏作为父。资源文件文本编辑器进行修改,否则向导将覆盖你的修改,其结果可能是不可取的。 IDR_MAINFRAME工具栏16,15动工 钮扣ID_FILE_NEW 分离器 分离器 分离器 分离器 分离器 分离器 60; 分离器 分离器 分离器 & #160;分离器 分离器 分离器 分离器 分离器 分离器 分离器 &# 160; 分离器 分离器 分离器 分离器 分离器 分离器 分离器  60; 分离器 分离器 分离器 分离器 分离器 分离器 分离器 0; 分离器 分离器 分离器 &# 160;分离器 分离器 分离器 分离器 分离器 分离器 分离器  60; 分离器 分离器 分离器 分离器 分离器 分离器 分离器  0; 分离器 分离器 分离器 分离器 钮扣ID_REFRESH 钮扣ID_EDIT_COPY 钮扣ID_FILE_SAVE 分离器 按钮ID_APP_ABOUT完
里面的CMainFrame::Create函数创建,组合框和字体。 HWND hWndToolBar = CreateSimpleToolBarCtrl(m_hWnd,IDR_MAINFRAME   ; 为FALSE,ATL_SIMPLE_TOOLBAR_​​PANE_STYLE);DWORD dwComboStyle = CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL |  60; WS_CHILD | WS_VISIBLE;dwComboStyle | = CBS_HASSTRINGS | CBS_OWNERDRAWFIXED;m_hWndComboBox =::CreateWindowEx(0,"COMBOBOXquot;,空,dwComboStyle 20,0,400,20,hWndToolBar,(HMENU)COMBOBOX_ID & #160; _Module.m_hInst,NULL);m_hFont = CreateFont(-14,/ / nHeight & #160; 0,/ / nWidth 0,/ / nEscapement 0,/ / nOrientation FW_BOLD,/ / nWeight 为FALSE,/ / bItalic 为FALSE,/ / bUnderline 0,/ / cStrikeOut ANSI_CHARSET,/ /的ncharset OUT_DEFAULT_PRECIS,/ / nOutPrecision  60; CLIP_DEFAULT_PRECIS,/ / nClipPrecision & #160; DEFAULT_QUALITY,/ / nQuality DEFAULT_PITCH | FF_SWISS,/ / PitchAndFamily &# 160; "的Comic Sans MSquot;);::SendMessage消息(m_hWndComboBox,(UINT)WM_SETFONT,(WPARAM)m_hFont,TRUE);
内的CMainFrame,WM_SIZE消息也实施,因此,改变大小时,CClientView将改变其大小,并放置在客户区中的图片。在这里,使用PostMessage的是,这样的客户端总是找出父窗口的面积。在SendMessage将无法工作。
你也将找到一个刷新或窗口指示器按钮。当你按下它,它就会围绕在组合框中选定的项目的窗口边框。其实,这是一个弹出窗口,在窗口的中间画一个空刷。这是我实现了它的方式,或可以使用DrawAnimatedRects功能。 LRESULT的CMainFrame::OnRefresh(WORD / * wNotifyCode * /,WORD / * WID * /   ; HWND / * hWndCtl bHandled * / BOOLamp; / * * /){ HWND hSavedWnd = BringToTheTop(); (5)睡眠; RECT rectFrom; ::GetWindowRect(hSavedWnd,放大器; rectFrom);/ / RECT rectTo;/ /:SetRect对(AMP rectTo,rectFrom.left,rectFrom.top/ / rectFrom.right,rectFrom.bottom);/ /:InflateRect(安培; rectTo,-100,-100);/ /::DrawAnimatedRects(hSavedWnd,IDANI_CAPTION/ /放大器; rectFrom,放大器; rectTo); WindowInfo WInfo = m_HanldeList [hSavedWnd]; (_stricmp(_T("计划Managerquot;),WInfo.m_strWindowTitle)) :InflateRect(AMP; rectFrom,8,8); INT nWidth = rectFrom.right - rectFrom.left; INT nHeight = rectFrom.bottom - rectFrom.top; ::SetWindowPos(m_BackGround,HWND_BOTTOM,rectFrom.left &# 160; rectFrom.top,nWidth,nHeight,SWP_SHOWWINDOW);  60; 睡眠(2000年); ::SetWindowPos(m_BackGround,HWND_TOP,rectFrom.left &# 160; rectFrom.top,nWidth,nHeight,SWP_HIDEWINDOW);  60; 返回0;}该方案的核心是增加枚举窗口列表框中。我们只在应用程序窗口(不是子窗口,或无形的窗口,或零大小窗口)感兴趣。
无效的CMainFrame::AddToTheList(HWND的HWND)TCHAR tchCurrentSelected [_MAX_PATH];  0;TCHAR tchBuffer [_MAX_PATH]; TCHAR tchClassName [_MAX_PATH]; TCHAR tchModuleName [_MAX_PATH]; HANDLE hProcess; ::GetWindowText函数(HWND,tchCurrentSelected,_MAX_PATH); INT nCount = 0; BOOL bChanged = FALSE; 做 {  0;bChanged = FALSE; nCount = SendMessage消息(m_hWndComboBox (UINT)CB_GETCOUNT,0,NULL); 为(int i = 0;我LT; nCount;我) { HWND的hSavedWnd =(HWND)的SendMessage函数(m_hWndComboBox  60; (UINT)CB_GETITEMDATA,我,NULL); & #160; (::IsWindow(hSavedWnd)== FALSE) {   ; ::SendMessage消息(m_hWndComboBox,CB_DELETESTRING,I,0); bChanged =真实; maplt;的HWND,WindowInfogt;:迭代名次=   ; m_HanldeList.find(hSavedWnd);  60; 如果(POS = m_HanldeList.end())! m_HanldeList.erase(POS); & #160; NSEL =::SendMessage消息(m_hWndComboBox,CB_FINDSTRING  60; -1,(LPARAM)(LPCTSTR)tchCurrentSelected);  0; NewSel =(NSEL == CB_ERR)? 0:NSEL;   ; SendMessage消息(m_hWndComboBox  0; (UINT)CB_SETCURSEL,NewSel,NULL);  0; 打破; }&# 160; } }而(bChanged); &# 160;(::IsWindow(HWND)== FALSE | |::IsWindowVisible(HWND) &# 160; == FALSE | |::GetParent(HWND)| | HWND == m_hWnd) 回报; ::GetWindowText函数(HWND,tchBuffer,_MAX_PATH); 如果(strlen的(tchBuffer)== 0) 回报;  60;INT nResult =::SendMessage消息(m_hWndComboBox,CB_FINDSTRING -1,(LPARAM)(LPCTSTR)tchBuffer); (nResult = CB_ERR)  60;{ 为(int i = 0;我LT; nCount;我) &# 160; { HWND的hSavedWnd =(HWND)的SendMessage函数(m_hWndComboBox   ; (UINT)CB_GETITEMDATA,我,NULL);  0; 如果(hSavedWnd == HWND) &# 160; 回报; }   ;} ::GetClassName(HWND,tchClassName,_MAX_PATH);  0; RECT RECT; ::GetWindowRect(HWND,放大器; RECT);&# 160; / /得到PID DWORD dwPID; GetWindowThreadProcessId(HWND,放大器; dwPID); hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,虚假,dwPID); GetModuleFileNameEx(hProcess,NULL,tchModuleName,_MAX_PATH);  0; CloseHandle(hProcess); 布尔bDoNoAccept =::IsWindow(HWND)== FALSE | | :IsWindowVisible(HWND)== FALSE,| | ::GetParent(HWND)| | HWND == m_hWnd; 如果(!bDoNoAccept) { maplt的HWND,WindowInfogt;:迭代器it = &# 160; m_HanldeList.find(HWND); BOOL bHidden =(rect.left == rect.right | | rect.top == rect.bottom); (== m_HanldeList.end()放大器;放大器; bHidden == FALSE)  0; { m_HanldeList.insert(STD:make_pair(HWND,  60; WindowInfo(tchBuffer,tchModuleName,dwPID))); nResult =::SendMessage消息(m_hWndComboBox,CB_ADDSTRING  0; 0,(LPARAM)(LPCTSTR)tchBuffer); (nResult = CB_ERR) ::SendMessage消息(m_hWndComboBox,CB_SETITEMDATA &# 160; nResult,(LPARAM)(HWND)的HWND); &# 160; nCount = SendMessage消息(m_hWndComboBox,(UINT)CB_GETCOUNT,0,NULL); INT CurSel = SendMessage消息(m_hWndComboBox  0; (UINT)CB_GETCURSEL,0,NULL); 如果(nCount放大器;放大器; CurSel == -1)  60; SendMessage消息(m_hWndComboBox,(UINT)CB_SETCURSEL,0,NULL); } }}
正如你可以看到,首先,我们发现应​​用程序窗口,然后我们发现它的过程中得到它的图标,这样我们就可以显示组合框里面。
我希望每个人都将享受这一方案。

回答

评论会员:BilloKhan 时间:2011/12/07
我已经改变了代码。现在,它也显示在状态行的应用程序。现在有新的工具栏上的按钮,如果你点击它会带你应用程序资源管理器内驻留,并复制到剪贴板的路径。

LRESULT CMainFrame中:OnExplorer(字/ * wNotifyCode * / / * WID * / HWND / * hWndCtl * /,BOOL bHandled一词)
{
INT CurSel = SendMessage消息(m_hWndComboBox,(UINT)CB_GETCURSEL,0,NULL);
的HWND hSavedWnd =(HWND)的SendMessage函数(m_hWndComboBox,(UINT)CB_GETITEMDATA,CurSel,NULL)
 0;WindowInfo WInfo = m_HanldeList [hSavedWnd]
字符tchArguments [MAX_PATH];

sprintf_s(tchArguments"/ E,/选择,%S",WInfo.m_strModuleName); WindowDir的char [MAX_PATH];
(GetWindowsDirectory(WindowDir,MAX_PATH)> 0)
{
strcat_s(WindowDir,"\ \ Explorer.exe的");
&# 160;
的ShellExecute(NULL,_T("打开"),WindowDir,tchArguments,NULL,SW_SHOWNORMAL); }

 60;(OpenClipboard())
{
 60;EmptyClipboard()
nLength = strlen的(WInfo.m_strModuleName)1; {BR HGLOBAL hClipboardData的GlobalAlloc(GMEM_DDESHARE,nLength)
  ; CHAR * pchData =(char *)的GlobalLock(hClipboardData)
strcpy_s(pchData,nLength,(LPCSTR)WInfo.m_strModuleName)

GlobalUnlock(hClipboardData);
SetClipboardData(CF_TEXT,hClipboardData); CloseClipboard();
} bHandled = FALSE;
返回0;}

阿迦汗

评论会员:游客 时间:2011/12/07
奔奔|关于2年以前,我也想作出类似的,但我停止在如何利用下拉菜单中的图片。你能给我一些有关此功能的的联系吗?感谢奔奔
BilloKhan
评论会员:游客 时间:2011/12/07
这是很容易。此链接的所有工具http://www.codeproject.com/clipboard/hscr2clp.asp但是他的节目不为我所知的工作,但您将能够建立包括鼠标和键盘钩子DLL。关于阿迦汗imgsrc=http://www.orcode.com/upimg/2011_12_07_04_47_17_2.gif
奔奔
评论会员:游客 时间:2011/12/07
非常感谢#65281;这是一个很好的主意(或许绝招imgsrc=http://www.orcode.com/upimg/2011_12_07_04_47_17_4.gif),但我发现一些共享支持自动捕获一个应用程序的所有下拉菜单,我。仍无法弄清楚它是如何工作的。你有什么想法?感谢奔奔
BilloKhan
评论会员:游客 时间:2011/12/07
我有钩应用程序发送到CodeProject上新的代码。保持观望。现在你可以利用下拉菜单中的图片。最好的问候阿迦汗{五}
急性| BilloKhan:我做了代码发送到CodeProject上,但它看起来像我不得不重写整篇文章
评论会员:。6Qing88 时间:2011/12/07
我觉得使用全球热键是一个简单的方法来实现你想要的能力。
最好的问候。
... ...
评论会员:StXh007 时间:2011/12/07
源码包不包括res文件夹
是的,我可以创造法克工具栏BMP和sony.bmp
但是,无法找到_splitpath_s,strcpy_s等功能
{七}
评论会员:BilloKhan 时间:2011/12/07
我很遗憾它不包含RES子文件夹,但现在它包含
_splitpath_s和strcpy_s都包含在C:\程序文件\微软的Visual Studio 8 \ VC \ \ stdlib.h中,但您也可以使用不带"_s"_splitpath和strcpy。他们是安全的功能。这是一个WTL的应用程序,真正的代码是在Win32。我希望这将有助于
关于
阿迦汗

- 修改,2006年11月14日15点51分(星期二)

如果你没有资源文件,而不是隐藏的资源,你可以从EXE或DLL文件中提取资源。
步骤一:创建一个虚拟的项目和你的VS 2005解决方案资源管理器"选项卡内dummy.rc文件上点击右键并选择"选项打开,并选择第二选项的资源编辑器。这将打开编辑潘dummy.rc(右侧)。
第二步:在同一地点选择打开/文件/打开并打开对话框会提示。选择wincap.exe。现在,你会发现,"打开"按钮小允许的基础上。如果你点击箭头下拉菜单,将弹出。选择"Openwith选项",然后选择第一个选项资源编辑器。第二个选项卡将打开在任何标签上右击并选择新的水平选项卡组。只需拖动从wincap.exe到您的虚拟资源文件的任何资源。
现在,您可以建立任何exe文件的水库。我希望这将有助于

评论会员:winne_ll 时间:2011/12/07
漂亮