VC小技巧(三)视图
1. 如何得到視圖指針
[ 問題提出]
現(xiàn)在你有一個(gè)多線程的Demo, 你想在多線程里處理視圖指針里的函數(shù), 我們給這個(gè)函數(shù)起個(gè)名字:Put(); 該如何實(shí)現(xiàn)呢?
// 有兩種方法可以實(shí)現(xiàn)你的要求:
//1) 第一種方法:
// 要是多線程不是在App.cpp 里出現(xiàn), 那么要在多線程的.cpp 中加上extern CYourApp theApp;
// 獲得文檔模板:
POSITION curTemplatePos = theApp.GetFirstDocTemplatePosition();
CDocTemplate *m_doc=theApp.GetNextDocTemplate(curTemplatePos);
// 獲得文檔:
curTemplatePos=m_doc->GetFirstDocPosition();
CYourDoc *m_pdoc=(CA8Doc*)m_doc->GetNextDoc(curTemplatePos);
// 獲得視圖:
curTemplatePos=m_pdoc->GetFirstViewPosition();
CYourView *m_pview=(CYourView*)m_pdoc->GetNextView(curTemplatePos);
// 調(diào)用視圖函數(shù):
m_pview->Put();
//2) 第二種方法:
// 獲得窗體指針:
CMainFrame *pFrame = (CMainFrame*)AfxGetApp()->m_pMainWnd;
// 獲得與該窗體符合的視圖:
CYourView *m_pView = (CYourView *) pFrame->GetActiveView();
// 調(diào)用視圖函數(shù):
m_pView->Put();
2. 如何設(shè)置有背景顏色的文本
(1)[ 解決方法]
用到了CDC::SetBkMode();
[ 程序?qū)崿F(xiàn)]
void CMyView::OnDraw(CDC* pDC)
{
CMyDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
CRect rcView;// 加這兩句
GetClientRect(rcView);
// TODO: add draw code for native data here
CString str (_T("Perfect Text ..."));
pDC->SetBkMode(TRANSPARENT);
rcView.OffsetRect (1,1);
pDC->SetTextColor(RGB (0,0,0));
pDC->DrawText(str,str.GetLength(),rcView,DT_SINGLELINE | DT_CENTER | DT_VCENTER);
rcView.OffsetRect(-1,-1);
pDC->SetTextColor(RGB (255,0,0));
pDC->DrawText(str,str.GetLength(),rcView,DT_SINGLELINE | DT_CENTER | DT_VCENTER);
}
(2) 建立名為My 的SDI 或MDI, 并響應(yīng)WM_ERASEBKGND.
BOOL CMyView::OnEraseBkgnd(CDC* pDC)
{
// TODO: Add your message handler code here and/or call default
CBrush Brush (RGB(114,147,171));
// Select the brush into the device context .
CBrush* pOldBrush = pDC->SelectObject(&Brush);
// Get the area that needs to be erased .
CRect ViewClip;
pDC->GetClipBox(&ViewClip);
//Paint the area.
pDC->PatBlt(ViewClip.left,ViewClip.top,ViewClip.Width(),ViewClip.Height(),PATCOPY);
//Unselect brush out of device context .
pDC->SelectObject (pOldBrush );
// Return nonzero to half fruther processing .
return TRUE;
return CView::OnEraseBkgnd(pDC);
}
此方法也適合基類是EditView 的SDI 或MDI 的情況, 但是字體的顏色和底色不行. 建議用WM_CTLCOLOR.
3.CDC 中的豎排文本
在OnDraw 成員函數(shù)中我想讓文本豎直對齊, 但CDC 類似乎不支持該處理
方法一: 如果你的豎直對齊是指旋轉(zhuǎn)文本的話, 下面的代碼會對你有幫助: 該代碼檢查一個(gè)Check box 控制, 查看文本是否需要旋轉(zhuǎn).
// m_pcfYTitle is a CFont* to the selected font.
// m_bTotateYTitle is a bool (==TRUE if rotated)
void CPage1::OnRotateytitle()
{
LOGFONT lgf;
m_pcfYTitle->GetLogFont(&lgf);
m_bRotateYTitle=
((CButton*)GetDlgItem(IDC_ROTATEYTITLE))->GetCheck()>0;
// escapement is reckoned clockwise in 1/10ths of a degree:
lgf.lfEscapement=-(m_bRotateYTitle*900);
m_pcfYTitle->DeleteObject();
m_pcfYTitle->CreateFontIndirect(&lgf);
DrawSampleChart();
}
注意如果你從CFontDialog 中選擇了不同的字體, 你應(yīng)該自己設(shè)定LOGFONT 的lfEscapement 成員. 將初始化后的lfEscapement 值傳到CFontDialog 中.
方法二: 還有一段代碼可參考:
LOGFONT LocalLogFont;
strcpy(LocalLogFont.lfFaceName, TypeFace);
LocalLogFont.lfWeight = fWeight;
LocalLogFont.lfEscapement = Orient;
LocalLogFont.lfOrientation = Orient;
if (MyFont.CreateFontIndirect(&LocalLogFont))
{
cMyOldFont = cdc->SelectObject(&MyFont);
}
4. 串太長時(shí)往讓其末尾顯示一個(gè)省略號( 在SDI 或MDI 的View 中)
[ 問題提出]
如何在串太長時(shí)往讓其末尾顯示一個(gè)省略號( 在SDI 或MDI 的View 中)?
[ 程序?qū)崿F(xiàn)]
建立名為My 的SDI 或MDI 工程.
void CMyView::OnDraw(CDC* pDC)
{
CMyDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
pDC->DrawText(CString("It ‘ s a long string,so we will add a ‘ ... ‘ ? at
the end."),CRect (110, 110, 180, 130),DT_LEFT | DT_END_ELLIPSIS);
//Add ellpsis to middle of string if it does not fit
pDC->DrawText(CString("It ‘ s a long string,so we will add a ‘ ... ‘ ? at
the end."),CRect (110, 140, 300, 160),DT_LEFT | DT_PATH_ELLIPSIS);
}
5. 修改視圖背景
How do I change the background color of a view?
To
change the background color for a CView, CFrameWnd, or CWnd object,
process the WM_ERASEBKGND message. The following code shows how:
BOOL CSampleView::OnEraseBkgnd(CDC* pDC)
{
// Set brush to desired background color.
CBrush backBrush(RGB(255, 128, 128));
// Save old brush.
CBrush* pOldBrush = pDC->SelectObject(&backBrush);
CRect rect;
pDC->GetClipBox(&rect);???? // Erase the area needed.
pDC->PatBlt(rect.left, rect.top, rect.Width(),
rect.Height(), PATCOPY);
pDC->SelectObject(pOldBrush);
return TRUE;
}
I solved the problem like this:
HBRUSH dlgtest::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
switch (nCtlColor)
{
case CTLCOLOR_BTN:
case CTLCOLOR_STATIC:
{
pDC->SetBkMode(TRANSPARENT);
}
case CTLCOLOR_DLG:
{
CBrush*???? back_brush;
COLORREF??? color;
color = (COLORREF) GetSysColor(COLOR_BTNFACE);
back_brush = new CBrush(color);
return (HBRUSH) (back_brush->m_hObject);
}
}
return(CFormView::OnCtlColor(pDC, pWnd, nCtlColor));
}
積累的VC 編程小技巧之打印相關(guān)
1. 修改打印預(yù)覽的ToolBar
為AFX_IDD_PREVIEW_TOOLBAR 這個(gè)ID 創(chuàng)建一個(gè)DialogBar 。則系統(tǒng)就會用新創(chuàng)建的DialogBar 代替系統(tǒng)默認(rèn)的那個(gè)
2. 關(guān)于打印
1. 要打印哪個(gè)視就
((CMainFrame*)AfxGetMainWnd())->m_wndSplitter.SetActivePane(...)
// 要打印的那個(gè)視對應(yīng)的Pane
2. 有一個(gè)單文檔工程,文檔窗口被切分:左視圖由CTreeView 的派生類管理,右視圖由CListView 的派生類CMyListView (其為風(fēng)格為LVS_REPORT )管理, 我想為右視圖添加打印和打印預(yù)覽,我在MyListView.cpp 中添加了
ON_COMMAND(ID_FILE_PRINT,CListView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW,CListView::OnFilePrintPreview) 還有
BOOL CMyListView::OnPreparePrinting(CPrintInfo* pInfo)
{
// TODO: call DoPreparePrinting to invoke the Print dialog box
// return CListView::OnPreparePrinting(pInfo);
pInfo->SetMaxPage(2);
BOOL bret=DoPreparePrinting(pInfo);
pInfo->m_nNumPreviewPages=2;
return bret;
}
3. 下面是從MSDN 中摘出來的一段,是用來改變消息路由的。用了這段代碼之后,CView 中的消息(菜單,控件,子窗口)將先被CMyShape 類來處理。不知道你要的是不是這樣的效果。
// This example illustrates extending the framework ‘ s standard command
// route from the view to objects managed by the view.? This example
// is from an object-oriented drawing application, similar to the
// DRAWCLI sample application, which draws and edits "shapes".
BOOL CMyView::OnCmdMsg(UINT nID, int nCode, void* pExtra,
AFX_CMDHANDLERINFO* pHandlerInfo)
{
// Extend the framework ‘ s command route from the view to
// the application-specific CMyShape that is currently selected
// in the view. m_pActiveShape is NULL if no shape object
// is currently selected in the view.
if ((m_pActiveShape != NULL)
&& m_pActiveShape->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
return TRUE;
// If the object(s) in the extended command route don ‘ t handle
// the command, then let the base class OnCmdMsg handle it.
return CView::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
}
// The command handler for ID_SHAPE_COLOR (menu command to change
// the color of the currently selected shape) was added to
// the message map of CMyShape (note, not CMyView) using ClassWizard.
// The menu item will be automatically enabled or disabled, depending
// on whether a CMyShape is currently selected in the view, that is,
// depending on whether CMyView::m_pActiveView is NULL.? It is not
// necessary to implement an ON_UPDATE_COMMAND_UI handler to enable
// or disable the menu item.
BEGIN_MESSAGE_MAP(CMyShape, CCmdTarget)
//{{AFX_MSG_MAP(CMyShape)
ON_COMMAND(ID_SHAPE_COLOR, OnShapeColor)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
如果你只是想調(diào)用OnFilePrint( ) 函數(shù),可以試一試下面的代碼,就和調(diào)用其它類中的函數(shù)一樣。
CMDIFrameWnd *pFrame =
(CMDIFrameWnd*)AfxGetApp()->m_pMainWnd;
// Get the active MDI child window.
CMDIChildWnd *pChild =
(CMDIChildWnd *) pFrame->GetActiveFrame();
// or CMDIChildWnd *pChild = pFrame->MDIGetActive();
// Get the active view attached to the active MDI child
// window.
CMyView *pView = (CMyView *) pChild->GetActiveView();
pView->OnFilePrint( );
4.
void CMyReportView::OnFileOpen()
{
char Filter[] = "Crystal Report files(*.rpt)|*.rpt|All files(*.*)|*.*||";
CRect rect;
CFileDialog OpenDlg(TRUE,0,0,OFN_HIDEREADONLY|OFN_FILEMUSTEXIST,(LPCTSTR)Filter,NULL);
if(OpenDlg.DoModal()!=IDOK) /// 顯示文件對話框
return;
CString m_fName=OpenDlg.GetPathName(); /// 取得文件名
if(m_CrystalReport)
m_CrystalReport.DestroyWindow();
GetClientRect(rect);
/// 創(chuàng)建控件///
if
(!m_CrystalReport.Create(AfxRegisterWndClass(0,
AfxGetApp()->LoadStandardCursor(IDC_ARROW)),WS_CHILD|WS_VISIBLE,rect,this,IDC_CRYSTALREPORT1))
{
AfxMessageBox(" 控件創(chuàng)建失敗!");
return ;
}
m_CrystalReport.SetWindowParentHandle((long)(this->m_hWnd));/// 設(shè)置父窗口
m_CrystalReport.SetWindowBorderStyle(0); /// 設(shè)置為沒有邊框
m_CrystalReport.SetWindowLeft(0); /// 左空間
m_CrystalReport.SetWindowTop(0); /// 頂部空間
m_CrystalReport.SetWindowControls(FALSE); /// 不顯示工具條
m_CrystalReport.SetReportFileName(m_fName); /// 設(shè)置報(bào)表文件
m_CrystalReport.SetWindowWidth(rect.Width()); /// 設(shè)置窗口寬度
m_CrystalReport.SetWindowHeight(rect.Height()); /// 設(shè)置窗口高度
m_CrystalReport.SetFormulas(0, "Company=/"VC 知識庫/""); /// 將報(bào)表中的Company 變量的值設(shè)置為VC 知識庫
m_CrystalReport.SetDestination(0); /// 設(shè)置輸出對象是屏幕
m_CrystalReport.PrintReport(); /// 顯示報(bào)表
}
void CMyReportView::OnFilePrint()
{
if(m_CrystalReport && m_CrystalReport.GetReportFileName() != "")
{
m_CrystalReport.SetDestination(1); /// 設(shè)置輸出對象是打印機(jī)
m_CrystalReport.PrintReport(); /// 打印
}
積累的VC 編程小技巧之文件操作
1. 刪除文件夾
// 刪除文件夾及其所有內(nèi)容
void CBaseDoc::RemoveFolder(const CString &strPathName)
{
CString path = strPathName;
if (path.Right(1) != _T("//"))
path += _T("//");
path += _T("*.*");
CFileFind ff;
BOOL res = ff.FindFile(path);
while (res)
{
res = ff.FindNextFile();
// 是文件時(shí)直接刪除
if (!ff.IsDots() && !ff.IsDirectory())
DeleteFile(ff.GetFilePath());
else if (ff.IsDots())
continue;
else if (ff.IsDirectory())
{
path = ff.GetFilePath();
// 是目錄時(shí)繼續(xù)遞歸,刪除該目錄下的文件
RemoveFolder(path);
::RemoveDirectory(path);
}
}
}
2. 遍歷整個(gè)目錄查找文件
在應(yīng)用程序的開發(fā)過程中,會遇到如何查找某一文件以確定此文件路徑的問題。利用CFileFind 類可以比較方便地在當(dāng)前目錄下進(jìn)行文件查找,但卻不能對其子目錄中的文件進(jìn)行搜尋。而實(shí)際應(yīng)用中往往需要對某一整個(gè)目錄樹,甚至是整個(gè)C 盤或D 盤驅(qū)動器進(jìn)行文件搜尋。通過實(shí)踐,我們在Visual C ++ 6.0 中編程實(shí)現(xiàn)了如何遍歷任意目錄樹,以查找某一特定的文件。
在下面的具體陳述中可以看到,在確定要查找的文件名和要進(jìn)行搜索的目錄的名稱后,將調(diào)用函數(shù)Search_Directory 進(jìn)行文件的查找。首先依次查找當(dāng)前目錄下的每一個(gè)實(shí)體(文件或是子目錄),如果是某一子目錄,則進(jìn)入該子目錄并遞歸調(diào)用函數(shù)Search_Dirctory 進(jìn)行查找,查找完畢之后, 再返回上一級目錄;如果不是子目錄而是某一文件,則判斷其是否就是我們要查找的文件,如果是則輸出其完整的文件路徑。這樣,通過Search_Directory 函數(shù)的反復(fù)遞歸調(diào)用,就可以實(shí)現(xiàn)對整個(gè)目錄,包括子目錄的遍歷搜索。下面將舉例詳細(xì)講述如何在VC ++中編程實(shí)現(xiàn)在整個(gè)目錄樹中的文件查找。
1 . 在Visual C ++ 6.0 (VC ++ 5.0 與之類似)中用默認(rèn)方式創(chuàng)建了一基于對話框的應(yīng)用程序Search 。在主窗口對話框上放置一命令按鈕,其Caption 為 “ Search File ” ,ID 為ID_BUTTON_SEARCH 。單擊此按鈕將完成文件的查找工作。
2 . 利用ClassWizard 為 “ Search File ” 按鈕的BN_CLICKED 事件添加處理函數(shù)OnButtonSearch ,代碼如下:
#include 〈direct.h 〉
#include 〈io.h 〉
void CSearchDlg::OnButtonSearch()
{
// TODO: Add your control notification handler code here
char szFilename[80];
// 字符串 szFilename 表示要查找的文件名
strcpy(szFilename,"Mytext.txt");
_chdir("d://"); // 進(jìn)入要查找的路徑(也可為某一具體的目錄)
// 查找文件, 如果查到則顯示文件的路徑全名
Search_Directory(szFilename);
// 為CSearchDlg 類的一成員函數(shù)
MessageBox( ″查找文件完畢! ″);
// 顯示查找完畢的信息
}
3. 在CSearchDlg 類中增加成員函數(shù)Search_Directory ,它將完成具體的文件查找工作,代碼如下:
void CSearchDlg::Search_Directory(char* szFilename)
{
long handle;
struct _finddata_t filestruct;
// 表示文件( 或目錄) 的信息
char path_search[_MAX_PATH];
// 表示查找到的路徑結(jié)果
// 開始查找工作, 找到當(dāng)前目錄下的第一個(gè)實(shí)體( 文件或子目錄) ,
// "*" 表示查找任何的文件或子目錄, filestruct 為查找結(jié)果
handle = _findfirst("*", &filestruct);
// 如果handle 為-1, 表示當(dāng)前目錄為空, 則結(jié)束查找而返回
if((handle == -1)) return;
// 檢查找到的第一個(gè)實(shí)體是否是一個(gè)目錄(filestruct.name 為其名稱)
if( ::GetFileAttributes(filestruct.name) & FILE_ATTRIBUTE_DIRECTORY )
{
// 如果是目錄, 則進(jìn)入該目錄并遞歸調(diào)用函數(shù)Search_Dirctory 進(jìn)行查找,
// 注意: 如果目錄名的首字符為 ‘ . ‘ ( 即為"." 或".."), 則不用進(jìn)行查找
if( filestruct.name[0] != ‘ . ‘ ? )
{
_chdir(filestruct.name);
Search_Directory(szFilename);
// 查找完畢之后, 返回上一級目錄
_chdir("..");
}
}
else // 如果第一個(gè)實(shí)體不是目錄, 則檢查是否是要查找的文件
{
// stricmp 對兩字符串進(jìn)行小寫形式的對比, 返回為0 表示完全一致
if( !stricmp(filestruct.name, szFilename) )
{
// 先獲得當(dāng)前工作目錄的全路徑
_getcwd(path_search,_MAX_PATH);
// 再獲得文件的完整的路徑名( 包含文件的名稱)
strcat(path_search,"//");
strcat(path_search,filestruct.name);
MessageBox(path_search); // 輸出顯示
}
}
// 繼續(xù)對當(dāng)前目錄中的下一個(gè)子目錄或文件進(jìn)行與上面同樣的查找
while(!(_findnext(handle,&filestruct)))
{
if( ::GetFileAttributes(filestruct.name) & FILE_ATTRIBUTE_DIRECTORY )
{
if(*filestruct.name != ‘ . ‘ )
{
_chdir(filestruct.name);
Search_Directory(szFilename);
_chdir("..");
}
}
else
{
if(!stricmp(filestruct.name,szFilename))
{
_getcwd(path_search,_MAX_PATH);
strcat(path_search,"//");
strcat(path_search,filestruct.name);
MessageBox(path_search);
}
}
}
_findclose(handle);
// 最后結(jié)束整個(gè)查找工作
}
這樣我們就可以對整個(gè)目錄進(jìn)行遍歷搜索,查找某一特定的文件,并輸出顯示其完整的文件路徑。以上的程序在Visual C ++ 6.0 中已調(diào)試通過。
3. 創(chuàng)建多級目錄
BOOL mkdirEx(const char* lpPath)
{
CString pathname = lpPath;
if(pathname.Right(1) != "/")
pathname += "/" ;
int end = pathname.ReverseFind( ‘ / ‘ );
int pt = pathname.Find( ‘ / ‘ );
if (pathname[pt-1] == ‘ : ‘ )
pt = pathname.Find( ‘ / ‘ , pt+1);
CString path;
while(pt != -1 && pt<=end)
{
path = pathname.Left(pt+1);
if(_access(path, 0) == -1)
_mkdir(path);
pt = pathname.Find( ‘ / ‘ , pt+1);
}
return true;
}
4. 創(chuàng)建包含多個(gè)子目錄的目錄
void CreateAllDirectories(CString strDir)
{
//remove ending / if exists
if(strDir.Right(1)=="//")
strDir=strDir.Left(strDir.GetLength()-1);
// base case . . .if directory exists
if(GetFileAttributes(strDir)!=-1)
return;
// recursive call, one less directory
int nFound = strDir.ReverseFind( ‘ // ‘ );
CreateAllDirectories(strDir.Left(nFound));
// actual work
CreateDirectory(strDir,NULL);
}
?
?
posted on 2010-06-26 23:31 butterflydog 閱讀(...) 評論(...) 編輯 收藏轉(zhuǎn)載于:https://www.cnblogs.com/neilwu/archive/2010/06/26/3099911.html
總結(jié)
以上是生活随笔為你收集整理的VC小技巧(三)视图的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 什么是存续期 两种常用的计算方式
- 下一篇: .NET速度的问题,不是最重要的