国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
VC編程小技巧之框架窗口及其他
積累的VC編程小技巧之框架窗口及其他

原 作 者:huzunbo

1.修改主窗口風(fēng)格



AppWizard生成的應(yīng)用程序框架的主窗口具有缺省的窗口風(fēng)格,比如在窗口標(biāo)題條中自動(dòng)添加文檔名、窗口是疊加型的、可改變窗口大小等。要修改窗口的缺省風(fēng)格,需要重載CWnd::PreCreateWindow(CREATESTRUCT& cs)函數(shù),并在其中修改CREATESTRUCT型參數(shù)cs。
CWnd::PreCreateWindow 函數(shù)先于窗口創(chuàng)建函數(shù)執(zhí)行。如果該函數(shù)被重載,則窗口創(chuàng)建函數(shù)將使用CWnd::PreCreateWindow 函數(shù)返回的CREATESTRUCT cs參數(shù)所定義的窗口風(fēng)格來創(chuàng)建窗口;否則使用預(yù)定義的窗口風(fēng)格。
CREATESTRUCT結(jié)構(gòu)定義了創(chuàng)建函數(shù)創(chuàng)建窗口所用的初始參數(shù),其定義如下:

typedef struct tagCREATESTRUCT {
LPVOID lpCreateParams; // 創(chuàng)建窗口的基本參數(shù)
HANDLE hInstance; // 擁有將創(chuàng)建的窗口的模塊實(shí)例句柄
HMENU hMenu; // 新窗口的菜單句柄
HWND hwndParent; // 新窗口的父窗口句柄
int cy; // 新窗口的高度
int cx; // 新窗口的寬度
int y; // 新窗口的左上角Y坐標(biāo)
int x; // 新窗口的左上角X坐標(biāo)
LONG style; // 新窗口的風(fēng)格
LPCSTR lpszName; // 新窗口的名稱
LPCSTR lpszClass; // 新窗口的窗口類名
DWORD dwExStyle; // 新窗口的擴(kuò)展參數(shù)
} CREATESTRUCT;

CREATESTRUCT結(jié)構(gòu)的style域定義了窗口的風(fēng)格。比如,缺省的MDI主窗口的風(fēng)格中就包括FWS_ADDTOTITLE(在標(biāo)題條中顯示當(dāng)前的工作文檔名)、FWS_PREFIXTITLE(把文檔名放在程序標(biāo)題的前面)、WS_THICKFRAME(窗口具有可縮放的邊框)等風(fēng)格。由于多種風(fēng)格參數(shù)由邏輯或(“|”)組合在一起的,因此添加某種風(fēng)格,就只需用“|”把對(duì)應(yīng)的參數(shù)加到CREATESTRUCT結(jié)構(gòu)的style域中;刪除已有的風(fēng)格,則需用“&”連接CREATESTRUCT結(jié)構(gòu)的style域與該風(fēng)格的邏輯非值。
CREATESTRUCT結(jié)構(gòu)的x、y、cx、cy域分別定義了窗口的初始位置和大小,因此,在CWnd::PreCreateWindow 函數(shù)中給它們賦值,將能定義窗口的初始顯示位置和大小。
下例中的代碼將主框窗口的大小將固定為1/4屏幕,標(biāo)題條中僅顯示窗口名,不顯示文檔名。

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs

// 修改主窗風(fēng)格
cs.style &= ~FWS_ADDTOTITLE; //去除標(biāo)題條中的文檔名
cs.style &= ~WS_THICKFRAME; //去除可改變大小的邊框
cs.style |= WS_DLGFRAME; //增加不能改變大小的邊框

// 確定主窗的大小和初始位置
int cxScreen = ::GetSystemMetrics(SM_CXSCREEN);//獲得屏幕寬
int cyScreen = ::GetSystemMetrics(SM_CYSCREEN); //獲得屏幕高
cs.x = 0; // 主窗位于左上角
cs.y = 0;
cs.cx = cxScreen/2; // 主窗寬為1/2屏幕寬
cs.cy = cxScreen/2; // 主窗高為1/2屏幕高
return CMDIFrameWnd::PreCreateWindow(cs);
}





2.窗口的分割與???nbsp;                     
                  



一、新建一個(gè)類CMySplitter,基類為CSplitterWnd



二、重載該類的OnMouseMove函數(shù):

void CMySplitter::OnMouseMove(UINT nFlags, CPoint point)
{ 
         // 限制切分條的運(yùn)動(dòng)范圍。 
         if(point.x<228||point.x>600) 
         { 
                 CWnd::OnMouseMove(nFlags, point); 
         } 
         else 
         { 
                 CSplitterWnd::OnMouseMove(nFlags, point); 
         } 
}


三、 然后就可以跟一般的窗口分割那樣去做了,if(point.x<228||point.x>600)這里的范圍可以隨你去設(shè)置了 ^_^,夠簡(jiǎn)單吧。



四、切分窗口
在MaiFram.h建立切分條對(duì)象:



protected:



CMySplitter m_wndSplitter; //切分窗口對(duì)象

//在MaiFram.cpp中實(shí)現(xiàn)窗口切分: 
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT /*lpcs*/,CCreateContext* pContext) 
{ 
         // 創(chuàng)建拆分器窗口 
if (!m_wndSplitter.CreateStatic(this, 1, 2)) 
                 return FALSE; 


if
(!m_wndSplitter.CreateView(0, 0,
RUNTIME_CLASS(CLeftView),CSize(228,100), pContext)
||!m_wndSplitter.CreateView(0,1, RUNTIME_CLASS(CDataEditView),  CSize(100, 100), pContext))

         { 
                 m_wndSplitter.DestroyWindow(); 
                 return FALSE; 
         } 
 
         return TRUE; 


}





3.如何使我的程序在啟動(dòng)時(shí)不創(chuàng)建一個(gè)新文檔



[問題]
如何使我的程序在啟動(dòng)時(shí)不創(chuàng)建一個(gè)新文檔?
[解答]
在程序的InitInstance中的ProcessShellCommand函數(shù)之前加入: cmdInfo.m_nShellCommand = CCommandLineInfo::FileNothing





4.初始化應(yīng)用程序的大小



如果想使應(yīng)用程序界面(文檔)在開始運(yùn)行是按你的尺寸展現(xiàn)在屏幕上,
  添加代碼如下:
  BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
  {
      int xsize=::GetSystemMetrics(SM_CXSCREEN);
      int ysize=::GetSystemMetrics(SM_CYSCREEN);
      cs.cx=xsize*5/10;
      cs.cy=ysize*5/10;
      cs.x=(xsize-cs.cx)/2;
      cs.y=(ysize-cs.cy)/2;  

  }
  其中的5/10是你的初始界面占屏幕的百分比,可以自己修改。如果想使應(yīng)用程序大小固定添加cs.style&=~WS_THICKFRAME;



5.如何全屏顯示(沒有標(biāo)題,沒有菜單,沒有工具條)



  [解決方法]
    重載CMainFrame的ActivateFrame函數(shù):
    void CMainFrame::ActivateFrame(int nCmdShow)
    {
         CRect cRectdesktop;
         WINDOWPLACEMENT windowplacement;
         ::GetWindowRect(::GetDesktopWindow(),&cRectdesktop);
         ::AdjustWindowRectEx(&cRectdesktop,GetStyle(),TRUE,GetExStyle());
         windowplacement.rcNormalPosition=cRectdesktop;
         windowplacement.showCmd=SW_SHOWNORMAL;
         SetWindowPlacement(&windowplacement);

         CFrameWnd::ActivateFrame(nCmdShow);



}



6.如何限制mdi子框架最大化時(shí)的大小



用ptMaxTrackSize代替prMaxSize,如下所示:



void CChildFrame::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI)
{
   // TOD Add your message handler code here and/or call default
   CChildFrame::OnGetMinMaxInfo(lpMMI);
   lpMMI->ptMaxTrackSize.x = 300;
   lpMMI->ptMaxTrackSize.y = 400;
}





7.程序如何刪除自己



/////////////////////////////////////////////////
 
int WINAPI WinMain(HINSTANCE h, HINSTANCE b, LPSTR psz, int n) {
 
// Is this the Original EXE or the clone EXE?
// If the command-line 1 argument, this is the Original EXE
// If the command-line >1 argument, this is the clone EXE
 
if (__argc == 1) {
 
// Original EXE: Spawn clone EXE to delete this EXE
// Copy this EXEcutable image into the user‘‘s temp directory
 
TCHAR szPathOrig[_MAX_PATH], szPathClone[_MAX_PATH];
GetModuleFileName(NULL, szPathOrig, _MAX_PATH);
GetTempPath(_MAX_PATH, szPathClone);
GetTempFileName(szPathClone, __TEXT("Del"), 0, szPathClone);
CopyFile(szPathOrig, szPathClone, FALSE);
 
//***注意了***:
// Open the clone EXE using FILE_FLAG_DELETE_ON_CLOSE
HANDLE hfile = CreateFile(szPathClone, 0, FILE_SHARE_READ, NULL, OPEN_EXISTI
NG, FILE_FLAG_DELETE_ON_CLOSE, NULL);
 
// Spawn the clone EXE passing it our EXE‘‘s process handle
// and the full path name to the Original EXE file.
TCHAR szCmdLine[512];
HANDLE hProcessOrig = OpenProcess(SYNCHRONIZE, TRUE, GetCurrentProcessId());

wsprintf(szCmdLine, __TEXT("%s %d \"%s\""), szPathClone, hProcessOrig, szPat
hOrig);
STARTUPINFO si;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
PROCESS_INFORMATION pi;
CreateProcess(NULL, szCmdLine, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
CloseHandle(hProcessOrig);
CloseHandle(hfile);
 
// This original process can now terminate.
} else {
// Clone EXE: When original EXE terminates, delete it
HANDLE hProcessOrig = (HANDLE) _ttoi(__targv[1]);
WaitForSingleObject(hProcessOrig, INFINITE);
CloseHandle(hProcessOrig);
DeleteFile(__targv[2]);
// Insert code here to remove the subdirectory too (if desired).
 
// The system will delete the clone EXE automatically
// because it was opened with FILE_FLAG_DELETE_ON_CLOSE
}
return(0);
}

2006-12-29 23:28:21
---------------------------------------------------------------
硬件之路~
第 1 樓 信息 | 留言 | QQ | Email | 主頁(yè) | 編輯 | 引用 | 管理
這一段程序思路很簡(jiǎn)單:不是不能在運(yùn)行時(shí)直接刪除本身嗎?好,那么程序先復(fù)制(CLONE)一個(gè)自己,用復(fù)制品起動(dòng)另一個(gè)進(jìn)程,然后自己結(jié)束運(yùn)行,則原來的EXE文件不被系統(tǒng)保護(hù).這時(shí)由新進(jìn)程作為殺手刪除原來的EXE文件,并且繼續(xù)完成程序其他的功能。

  新進(jìn)程在運(yùn)行結(jié)束后,復(fù)制品被自動(dòng)刪除。這又是值得介紹的一個(gè)把戲了,注意:

// Open the clone EXE using FILE_FLAG_DELETE_ON_CLOSE
HANDLE hfile = CreateFile(szPathClone, 0, FILE_SHARE_READ, NULL,OPEN_EXISTIN
G, FILE_FLAG_DELETE_ON_CLOSE, NULL);
 
 這里面的FILE_FLAG_DELETE_ON_CLOSE標(biāo)志,這個(gè)標(biāo)志是告訴操作系統(tǒng),當(dāng)和這個(gè)文件相關(guān)的所有句柄都被關(guān)閉之后(包括上面這個(gè)
CREATEFILE創(chuàng)建的句炳),就把這個(gè)文件刪除。幾乎所有的臨時(shí)文件在創(chuàng)建時(shí),都指明了這個(gè)標(biāo)志。另外要注意的是:在復(fù)制品進(jìn)程對(duì)原始程序操刀之
前,應(yīng)該等待原進(jìn)程退出.在這里用的是進(jìn)程同步技術(shù).用HANDLE hProcessOrig =
OpenProcess(SYNCHRONIZE,
TRUE,GetCurrentProcessId());得到原進(jìn)程句柄.SYNCHRONICE標(biāo)志在NT下有效,作用是使OpenProcess得
到的句柄可以做為同步對(duì)象.復(fù)制品進(jìn)程用WaitForSingleObject函數(shù)進(jìn)行同步,然后一個(gè)DeleteFile,以及進(jìn)行其它銷毀證據(jù)(比
如刪目錄)的工作,一切就完事了。
 
  程序是基于CONSOLE的,通過傳入的參數(shù)確定是原始的進(jìn)程還是復(fù)制品新進(jìn)程,并且得到需要操
作的目標(biāo)文件的信息(主要是路徑),復(fù)制品放在系統(tǒng)的TEMP目錄(GetTempPath得到),你也可以隨便找個(gè)你認(rèn)為安全的地方(比如:
WINDOWS\SYSTEM32等等)。這里面沒有甚么深的技術(shù).再看其他的一些實(shí)現(xiàn)刪除自己的例子,比如說在進(jìn)程退出前,用fwrite等方法輸出一
個(gè).BAT文件,在里面寫幾句DEL,然后WINEXEC一下這個(gè)BAT文件即可.玩兒過DOS的蟲蟲大多都會(huì)。



8.如何實(shí)現(xiàn)SDI與MDI的轉(zhuǎn)換



我想將一個(gè)編好的SDI應(yīng)用程序轉(zhuǎn)換為MDI,很明顯要有多處的改變。



你可以這樣做:建立一個(gè)繼承于CMDIChidWnd的類,不防設(shè)為CChldFrm.在CWinApp中作如下變化。




InitInstance()
{
. ...
    //instead of adding CSingleDocTemplate
    // Add CMultiDocTemplate.
    pDocTemplate = new CMultiDocTemplate(
           IDR_MAINFRAME,
           RUNTIME_CLASS(CSDIDoc),
           RUNTIME_CLASS(CChldFrm),
// For Main MDI Frame change this frame window from
// CFrameWnd derivative ( i.e. CMainFrame )
// to your CMDIChildWnd derived CChldFrm.
           RUNTIME_CLASS(CSDIView));
/// After this it is required to create the main frame window
// which will contain all the child windows. Now this window is
// what was initially frame window for SDI.
    CMainFrame* pMainFrame = new CMainFrame;
    if (!pMainFrame->LoadFrame(IDR_MAINFRAME))
            return FALSE;
     m_pMainWnd = pMainFrame;
.....
}



在從CMDIFrameWnd中繼承的類CMainFrame代替CFramWnd后,所有的類都將從CMDIFrame繼承,而不是CFrameWnd,編譯運(yùn)行后你就會(huì)發(fā)現(xiàn)程序已經(jīng)從SDI變換到MDI。
注意:在CMainFram中必須將構(gòu)造函數(shù)從private改為public.否則會(huì)出錯(cuò)。



9.想在程序一啟動(dòng)時(shí)就自動(dòng)關(guān)閉窗口,不在任務(wù)欄里顯示



CTRL+W打開ClassWizard;
點(diǎn)擊Class Info頁(yè),類名是工程名Dlg,
再在左下方的"Filter"中選擇"Windows";
回到Message Maps頁(yè),就可以看到消息中有WM_WINDOWPOSCHANGING,
加入代碼,如上所示.
這樣運(yùn)行*.EXE,不但看不到主界面,任務(wù)欄也沒有,就是任務(wù)管理器中的"應(yīng)用程序"中也不列出,那該如何關(guān)閉它?
在任務(wù)管理器的"進(jìn)程"中可以找到它,這是黑客程序常用的方法.
如果需要的話,"進(jìn)程"中也看不到.這樣要終止它就是問題了





10.如何修改frame窗口的背景顏色



MDI窗口的客戶區(qū)是由frame窗口擁有的另一個(gè)窗口覆蓋的。為了改變frame窗口背景的顏色,只需要這個(gè)客戶區(qū)的背景顏色就可以了。你必須自己處理WM_ERASEBKND消息。下面是工作步驟:
  創(chuàng)建一個(gè)從CWnd類繼承的類,就叫它CMDIClient吧;
  在CMDIFrameWnd中加入CMDIClient變量;(具體情況看下面的代碼)
#include "MDIClient.h"
class CMainFrame : public CMDIFrameWnd
{
...
protected:
CMDIClient m_wndMDIClient;
}
  重載CMDIFrameWnd::OnCreateClient,下面是這段代碼,請(qǐng)注意其中的SubclassWindow();
 
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
if ( CMDIFrameWnd::OnCreateClient(lpcs, pContext) )
{
m_wndMDIClient.SubclassWindow(m_hWndMDIClient);
return TRUE;
}
else
return FALSE;
}
  最后要在CMDIClient中加入處理WM_ERASEBKGND的函數(shù)。





11.在MFC下實(shí)現(xiàn)圖像放大鏡



一、 引言



當(dāng)我們想仔細(xì)觀察某個(gè)細(xì)微的東西時(shí),一般都會(huì)使用放大鏡。而要看清顯示在計(jì)算機(jī)屏幕上的圖片或文字時(shí)通常也



可以借助于Windows操作系統(tǒng)附帶的放大程序來實(shí)現(xiàn)。但該程序只能以固定的放大倍數(shù)
去進(jìn)行觀看,有時(shí)并不能滿足我們的需要。本文就通過MFC基本類庫(kù)提供的StretchBlt函數(shù)來實(shí)現(xiàn)對(duì)屏幕圖象的局部放大,并且可以隨意放大、縮小,
選取到合適的放大倍數(shù)來對(duì)圖像的細(xì)節(jié)進(jìn)行觀察。



二、 設(shè)計(jì)與實(shí)現(xiàn)



本程序主要用來對(duì)圖像的局部進(jìn)行可調(diào)倍數(shù)的放大,應(yīng)當(dāng)具有以下主要功能:



1. 移動(dòng)MOUSE放大顯示圖像的不同部位



2. 左擊增加放大倍率、右擊減少放大倍率。



從光學(xué)角度來看,對(duì)物體的放大成像是通過把較小的真實(shí)物體顯示成尺寸較大的虛像來實(shí)現(xiàn)的。因此我們可以用類



似的原理,把圖像中待放大的區(qū)間從較小的顯示范圍拉伸到一個(gè)比較大的顯示范圍即可達(dá)到圖
像放大的效果,兩個(gè)區(qū)間的比值也就是圖像的放大倍率??梢酝ㄟ^縮小源區(qū)間的范圍或擴(kuò)大放大區(qū)間的范圍來實(shí)現(xiàn)放大倍率的調(diào)整。在MFC基本類庫(kù)中提供有
CDC類的StretchBlt函數(shù)可以將一幅位圖從一個(gè)源矩形以一定的光柵操作拷貝到另外一個(gè)不同大小的目標(biāo)矩形中去,因此可以用此函數(shù)來實(shí)現(xiàn)圖象放大
的功能,其函數(shù)原形聲明如下:



BOOL StretchBlt( int x, int y, //目標(biāo)矩形的坐標(biāo)原點(diǎn)



int nWidth, int nHeight, //目標(biāo)矩形的長(zhǎng)度和寬度



CDC* pSrcDC, //源設(shè)備環(huán)境句柄



int xSrc, int ySrc, //源矩形的坐標(biāo)原點(diǎn)



int nSrcWidth, int nSrcHeight, //源矩形的長(zhǎng)度和寬度



DWORD dwRop ); //光柵操作標(biāo)志



當(dāng)指定的源和目標(biāo)矩形的寬度或高度不一樣時(shí),StretchBlt函數(shù)將創(chuàng)建一個(gè)位圖的鏡像。如果是寬度有變化,就沿x軸創(chuàng)建鏡像;如果是高度上有變化就沿y軸創(chuàng)建鏡像。而且該函數(shù)可以在內(nèi)存中對(duì)源圖象做拉伸或壓縮處理后再拷貝到目標(biāo)矩形中去。



要放大圖像首先要把圖像顯示出來,一般可以從文件動(dòng)態(tài)裝載或者直接從資源中用LoadBitMap讀取位圖資源。下面的代碼放在視類的OnDraw函數(shù)中,用以在第一次調(diào)用時(shí)將位圖裝載并顯示出來,以后再被調(diào)用只是負(fù)責(zé)重畫:



……



static bool load;



if (!load)



{



BITMAP bm;



load = !load;



//裝載位圖到 m_pBitmap



m_pBitmap->LoadBitmap(IDB_BITMAP1);



//創(chuàng)建相關(guān)的設(shè)備環(huán)境



m_pdcMem->CreateCompatibleDC(pDC);



//將位圖從m_ pBitmap中裝載到m_pdcMem中



m_pdcMem->SelectObject(m_pBitmap);



m_pBitmap->GetObject(sizeof(bm),&bm);



m_sizeSource.cx = bm.bmWidth;



m_sizeSource.cy = bm.bmHeight;



m_sizeDest = m_sizeSource;



//把位圖從m_pdcMem中裝載到當(dāng)前正在使用的設(shè)備環(huán)境中



pDC->StretchBlt(0,0,m_sizeSource.cx,m_sizeSource.cy,m_pdcMem,0,0,m_sizeSource.cx,m_sizeSource.cy,mana);



}



else



{



//重畫圖像



pDC->StretchBlt(0,0,m_sizeSource.cx,m_sizeSource.cy,m_pdcMem,0,0,m_sizeSource.cx,m_sizeSource.cy,mana);



SetCursor(NULL);//隱藏鼠標(biāo)



}



要實(shí)現(xiàn)前面提到的第一個(gè)功能:移動(dòng)MOUSE放大顯示圖像的不同部位,顯然首先要在
WM_MOUSEMOVE消息的響應(yīng)函數(shù)里編寫代碼。以整形變量s和d來分別表示所選取的源和目標(biāo)區(qū)域的大小,再通過消息響應(yīng)函數(shù)OnMouseMove
的入口參數(shù)point來確定當(dāng)前的鼠標(biāo)位置就可以計(jì)算出我們要選取的源和目標(biāo)區(qū)域在圖像的位置。放大的工作只需通過StretchBlt函數(shù)將源區(qū)域中所
在的圖像拉伸到目標(biāo)矩形那么大,并拷貝給目標(biāo)區(qū)域即可實(shí)現(xiàn)所選區(qū)域的放大效果,下面是部分主要代碼:



……



//確定目標(biāo)區(qū)域、源區(qū)域的坐標(biāo)位置



CRect srect,drect,mrect;



srect.left = point.x - s;



srect.top = point.y - s;



srect.right = point.x + s;



srect.bottom = point.y + s;



drect.left = point.x - d;



drect.top = point.y - d;



drect.right = point.x + d;



drect.bottom = point.y + d;



mrect.left = oldx - d;



mrect.top = oldy - d;



mrect.right = oldx + d;



mrect.bottom = oldy + d;



dd = 2*d;



//獲取可用設(shè)備環(huán)境句柄



CDC * pDC = GetDC();



OnPrepareDC(pDC);



if (recover)



{



pDC->BitBlt(mrect.left,mrect.top,dd,dd,m_pdcMem,mrect.left,mrect.top,mana);



}



//隱藏鼠標(biāo)



SetCursor(NULL);



//拉伸放大



pDC->StretchBlt(drect.left,drect.top,drect.Width(),drect.Height(),m_pdcMem,srect.left,srect.top,srect.Width(),srect.Height(),SRCCOPY);



//保存當(dāng)前鼠標(biāo)位置備用



oldx = point.x; oldy = point.y;



//釋放設(shè)備環(huán)境句柄



ReleaseDC(pDC);



recover = true;



……



為了實(shí)現(xiàn)第二個(gè)功能:左擊增加放大倍率、右擊減少放大倍率,可以分別在消息
WM_LBUTTONDOWN和消息WM_RBUTTONDOWN中添加改變選取區(qū)域大小的代碼來實(shí)現(xiàn)。如果選取源矩形不變而改變目標(biāo)矩形的大小會(huì)隨著放
大倍數(shù)的增大,顯示區(qū)域也不斷增大,當(dāng)放大到一定程度的時(shí)候會(huì)另人無法忍受,因此選取通過縮放源矩形大小來控制放大倍數(shù)的方案:



void CZoomInView::OnRButtonDown(UINT nFlags, CPoint point)



{



if (s < 60)



{



SetCursor(NULL);



s+=3;



OnMouseMove(nFlags, point);



}



CView::OnRButtonDown(nFlags, point);



}



……



void CZoomInView::OnLButtonDown(UINT nFlags, CPoint point)



{



if(s>5)



{



s-=3;



SetCursor(NULL);



OnMouseMove(nFlags, point);



}



CView::OnLButtonDown(nFlags, point);



}



(完)

2006-12-29 23:29:49
---------------------------------------------------------------
硬件之路~
第 2 樓 信息 | 留言 | QQ | Email | 主頁(yè) | 編輯 | 引用 | 管理

積累的VC編程小技巧之圖標(biāo)、光標(biāo)及位圖



1.圖標(biāo)透明



(1).Windows中的圖標(biāo)其實(shí)是有兩個(gè)圖像組成的,其中一個(gè)用于與它要顯示的位置的圖像做“AND”操作,另一個(gè)作“XOR”操作。

透明:用“白色”AND,用“黑色”XOR
反色:用“白色”AND,用“白色”XOR
正常色:用“黑色”AND,用正常顏色XOR.
(2). WIN9X中好像是對(duì)像素的操作實(shí)現(xiàn)透明的
WIN2K中就有API直接實(shí)現(xiàn)透明了!
WIN2K中
GetWindowLong
SetWindowLong
SetLayeredWindowAttributes
三個(gè)API就可以實(shí)現(xiàn)透明了!
(3) 


::DrawIconEx(pDC->GetSafeHdc(),point.x,point.y,icon,icosize,icosize,0,NULL,DI_NORMAL);





2.如何獲得其他程序的圖標(biāo),并顯示在View中



  [問題提出]
  有的時(shí)候,如:類資源管理器會(huì)遇到獲得程序圖標(biāo)并顯示的操作,如何實(shí)現(xiàn)呢?
  [解決方法]
  SDK函數(shù)SHGetFileInfo來獲得有關(guān)文件的很多信息:如大小圖標(biāo),屬性,類型等.
  [程序?qū)崿F(xiàn)]
  建立名為My的SDI工程.在OnPaint()函數(shù)中加入:
  void CMyView::OnPaint()
  {
   CPaintDC dc(this); // device context for painting
   HICON hIcon=:: ExtractIcon(AfxGetInstanceHandle(),_T("NotePad.exe"),0);
   if (hIcon && hIcon!=(HICON)-1)
   dc.DrawIcon(10,10,hIcon);

   // TODO: Add your message handler code here
   // Do not call CView::OnPaint() for painting messages
  }
  說明:_T("NotePad.exe")指的是要獲得什么程序的圖標(biāo).
  或者在OnDraw()中(此時(shí)必須保證沒有OnPaint()函數(shù),想想為何?)
  void CMyView::OnDraw(CDC* pDC)
  {
   CMyDoc* pDoc = GetDocument();
   ASSERT_VALID(pDoc);
   // TODO: add draw code for native data here
   HICON hIcon=:: ExtractIcon(AfxGetInstanceHandle(),_T("NotePad.exe"),0);
   if (hIcon &&hIcon!=(HICON)-1)
   pDC->DrawIcon(10,10,hIcon);
  }





3.如何改變默認(rèn)的光標(biāo)形狀



在對(duì)話框/窗口/你需要的地方加上對(duì)WM_SETCURSOR消息的處理.



BOOL MyDialog::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
    // TOD Add your message handler code here and/or call default
    ::SetCursor(AfxGetApp()->LoadCursor(IDC_MYCURSOR));
    return TRUE;
    //return CDialog::OnSetCursor(pWnd, nHitTest, message);
}
窗口類光標(biāo)風(fēng)格不能為NULL.





4.改變應(yīng)用程序的圖標(biāo)靜態(tài)更改



  修改圖標(biāo)資源IDR_MAINFRAME。它有兩個(gè)圖標(biāo),一個(gè)是16*16的,另一個(gè)是32*32的,注意要一起修改。



  動(dòng)態(tài)更改: 向主窗口發(fā)送WM_SETICON消息.代碼如下:



HICON hIcon=AfxGetApp()->LoadIcon(IDI_ICON);
ASSERT(hIcon);
AfxGetMainWnd()->SendMessage(WM_SETICON,TRUE,(LPARAM)hIcon);





5.更改窗口圖標(biāo)并將其顯示在任務(wù)欄



以下兩個(gè)函數(shù)可以為應(yīng)用程序中的各子窗口顯示一個(gè)任務(wù)條到任務(wù)欄并更改它們的圖標(biāo)。對(duì)那些象QQ一樣隱藏主窗口的應(yīng)用程序特別有用。

//函數(shù)用途:更改一個(gè)窗口的圖標(biāo)并將其顯示在任務(wù)欄、任務(wù)切換條、任務(wù)管理器里
//參數(shù)說明:
//hWnd
要改變圖標(biāo)的窗口句柄
//hLargeIcon 顯示到任務(wù)切換條上的圖標(biāo) 32*32
//hSmallIcon
顯示到除任務(wù)切換條之外的圖標(biāo) 16*16
//hIcon
顯示的圖標(biāo),32*32,在顯示到任務(wù)切換條之外的其余地方時(shí)會(huì)被自動(dòng)壓縮成16*16的。
//注釋:
//此函數(shù)對(duì)于模式對(duì)話框無能為力。
//如果HICON NULL,函數(shù)不改變窗口圖標(biāo),但是將原有圖標(biāo)顯示到任務(wù)欄、
// 任務(wù)切換條、任務(wù)管理器里。
//此函數(shù)是通過將窗口的父窗口指針置空來實(shí)現(xiàn)將圖標(biāo)顯示到任務(wù)欄、任務(wù)切換條、
// 任務(wù)管理器里的,所以調(diào)用完成后,其父窗口指針不再可用。
BOOL SendWndIconToTaskbar(HWND hWnd,HICON hLargeIcon,HICON hSmallIcon);
BOOL SendWndIconToTaskbar(HWND hWnd,HICON hIcon);
BOOL CUIApp::SendWndIconToTaskbar(HWND hWnd,HICON hLargeIcon,HICON hSmallIcon)
{
 BOOL ret = TRUE;
 ASSERT(hWnd);
 if(!::IsWindow(hWnd))
  return FALSE;
 //獲取窗口指針
 CWnd* pWnd;
 pWnd = pWnd->FromHandle(hWnd);
 ASSERT(pWnd);
 if(!pWnd)
  return FALSE;
 //將父窗口設(shè)為NULL
 if(pWnd->GetParent())
  if(::SetWindowLong(hWnd,GWL_HWNDPARENT,NULL) == 0)
   return FALSE;

  if(!(pWnd->ModifyStyle(NULL,WS_OVERLAPPEDWINDOW)))
   ret = FALSE;
  //設(shè)置窗口圖標(biāo)
  if(hLargeIcon && hSmallIcon)
  {
   pWnd->SetIcon(hSmallIcon,FALSE);
   pWnd->SetIcon(hLargeIcon,TRUE);
  }

  return ret;
 }

BOOL CUIApp::SendWndIconToTaskbar(HWND hWnd,HICON hIcon)
{
 BOOL ret = TRUE;
 ASSERT(hWnd);
 if(!::IsWindow(hWnd))
  return FALSE;
  //獲取窗口指針
 CWnd* pWnd;
 pWnd = pWnd->FromHandle(hWnd);
 ASSERT(pWnd);
 if(!pWnd)
  return FALSE;
 //將父窗口設(shè)為NULL
 if(pWnd->GetParent())
  if(::SetWindowLong(hWnd,GWL_HWNDPARENT,NULL) == 0)
   return FALSE;

 if(!(pWnd->ModifyStyle(NULL,WS_OVERLAPPEDWINDOW)))
  ret = FALSE;
 //設(shè)置窗口圖標(biāo)
 pWnd->SetIcon(hIcon,TRUE);
 pWnd->SetIcon(hIcon,FALSE);

 return ret;
}





6.如何將位圖縮放顯示在Static控件中



//在Staic控件內(nèi)顯示位圖
void CShowBmpInDlgDlg::ShowBmpInStaic()
{
    CBitmap hbmp;
    HBITMAP hbitmap;
    //將pStatic指向要顯示的地方
    CStatic *pStaic;
    pStaic=(CStatic*)GetDlgItem(IDC_IMAGE);
    //裝載資源 MM.bmp是我的一個(gè)文件名,用你的替換
    hbitmap=(HBITMAP)::LoadImage (::AfxGetInstanceHandle(),"MM.bmp",
        IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_CREATEDIBSECTION);
    
    hbmp.Attach(hbitmap);
    //獲取圖片格式
    BITMAP bm;
    hbmp.GetBitmap(&bm);
    CDC dcMem;
    dcMem.CreateCompatibleDC(GetDC());
    CBitmap *poldBitmap=(CBitmap*)dcMem.SelectObject(hbmp);
    CRect lRect;
    pStaic->GetClientRect(&lRect);
    //顯示位圖
    pStaic->GetDC()->StretchBlt(lRect.left ,lRect.top ,lRect.Width(),lRect.Height(),
        &dcMem,0 ,0,bm.bmWidth,bm.bmHeight,SRCCOPY);
    dcMem.SelectObject(&poldBitmap);
}



2006-12-29 23:30:45
---------------------------------------------------------------
硬件之路~
第 3 樓 信息 | 留言 | QQ | Email | 主頁(yè) | 編輯 | 引用 | 管理
          
          
            積累的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ù)中我想讓文本豎直對(duì)齊,但CDC類似乎不支持該處理



方法一:如果你的豎直對(duì)齊是指旋轉(zhuǎn)文本的話,下面的代碼會(huì)對(duì)你有幫助:該代碼檢查一個(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.串太長(zhǎng)時(shí)往讓其末尾顯示一個(gè)省略號(hào)(在SDI或MDI的View中)



  [問題提出]
    如何在串太長(zhǎng)時(shí)往讓其末尾顯示一個(gè)省略號(hào)(在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));
}



2006-12-29 23:32:06
---------------------------------------------------------------
硬件之路~
第 4 樓 信息 | 留言 | QQ | Email | 主頁(yè) | 編輯 | 引用 | 管理
          
          
          
    積累的VC編程小技巧之打印相關(guān)

1.修改打印預(yù)覽的ToolBar



為AFX_IDD_PREVIEW_TOOLBAR這個(gè)ID創(chuàng)建一個(gè)DialogBar。則系統(tǒng)就會(huì)用新創(chuàng)建的DialogBar代替系統(tǒng)默認(rèn)的那個(gè)



2.關(guān)于打印



1.要打印哪個(gè)視就
((CMainFrame*)AfxGetMainWnd())->m_wndSplitter.SetActivePane(...)



//要打印的那個(gè)視對(duì)應(yīng)的Pane





2.有一個(gè)單文檔工程,文檔窗口被切分:左視圖由CTreeView 的派生類管理,右視圖由CListView 的派生類CMyListView(其為風(fēng)格為L(zhǎng)VS_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) ///顯示文件對(duì)話框
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知識(shí)庫(kù)\""); ///將報(bào)表中的Company變量的值設(shè)置為VC知識(shí)庫(kù)
m_CrystalReport.SetDestination(0); ///設(shè)置輸出對(duì)象是屏幕
m_CrystalReport.PrintReport(); ///顯示報(bào)表
}
void CMyReportView::OnFilePrint()
{
if(m_CrystalReport && m_CrystalReport.GetReportFileName() != "")
{
m_CrystalReport.SetDestination(1); ///設(shè)置輸出對(duì)象是打印機(jī)
m_CrystalReport.PrintReport(); ///打印



}



2006-12-29 23:33:30
---------------------------------------------------------------
硬件之路~
第 5 樓 信息 | 留言 | QQ | Email | 主頁(yè) | 編輯 | 引用 | 管理
          
          
        積累的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ā)過程中,會(huì)遇到如何查找某一文件以確定此文件路徑的問題。利用CFileFind類可以比較方便地在當(dāng)前目錄下進(jìn)行文件查找,但卻不能對(duì)其子目錄中的文件進(jìn)行搜尋。而實(shí)際應(yīng)用中往往需要對(duì)某一整個(gè)目錄樹,甚至是整個(gè)C盤或D盤驅(qū)動(dòng)器進(jìn)行文件搜尋。通過實(shí)踐,我們?cè)赩isual 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)行查找,查找完畢之后, 再返回上一級(jí)目錄;如果不是子目錄而是某一文件,則判斷其是否就是我們要查找的文件,如果是則輸出其完整的文件路徑。這樣,通過Search_Directory函數(shù)的反復(fù)遞歸調(diào)用,就可以實(shí)現(xiàn)對(duì)整個(gè)目錄,包括子目錄的遍歷搜索。下面將舉例詳細(xì)講述如何在VC++中編程實(shí)現(xiàn)在整個(gè)目錄樹中的文件查找。
  1. 在Visual C++ 6.0(VC++ 5.0與之類似)中用默認(rèn)方式創(chuàng)建了一基于對(duì)話框的應(yīng)用程序Search。在主窗口對(duì)話框上放置一命令按鈕,其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);
         // 查找完畢之后, 返回上一級(jí)目錄
         _chdir("..");
      }
   }
   else // 如果第一個(gè)實(shí)體不是目錄, 則檢查是否是要查找的文件
   {
      // stricmp對(duì)兩字符串進(jìn)行小寫形式的對(duì)比, 返回為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ù)對(duì)當(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è)查找工作
}
  這樣我們就可以對(duì)整個(gè)目錄進(jìn)行遍歷搜索,查找某一特定的文件,并輸出顯示其完整的文件路徑。以上的程序在Visual C++ 6.0中已調(diào)試通過。





3.創(chuàng)建多級(jí)目錄



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);
}


2006-12-29 23:34:34
---------------------------------------------------------------
硬件之路~
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
總結(jié):VC小知識(shí)!
VC窗體設(shè)計(jì)集錦
VC小技巧20個(gè)-C/C++
CStatic控件的基本使用
VC 中的字體設(shè)置
VC中句柄、指針、ID之間的轉(zhuǎn)換
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服