简介
有许多屏幕捕捉程序,但我不与他们最高兴的。所以我做了自己的屏幕捕捉程序。这项计划将不会为您提供的设施进行拍照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); } }}
正如你可以看到,首先,我们发现应用程序窗口,然后我们发现它的过程中得到它的图标,这样我们就可以显示组合框里面。
我希望每个人都将享受这一方案。