vc比较实用方法与比较难找代码

1.        如何获取系统日期

CTime tm = CTime :: GetCurrentTime();

CString strTime = tm.Format(_TEXT(“%Y-%M-%d %H:%M:%S));

MessageBox(strTime);

 

2.        动态分配二维数组

int **array;

array = new int*[col];

if(array = = 0) exit(-1);

for(int i=0; i<col; i++){

array[i] = new int[row];

if(array[i] = = 0)

    exit(-1); }

//释放

for(i=0; i<col; i++){

 delete [] array[i]; }

delete [] array;

 

3.        如何定义一个二维字符串数组

①      char **str = “abcdef” ; //一维

②      char *str[row][col]={“abc”, “cdf”, “efg”…..}; //row×col个

 

4.        将一个十六进制”FF”、”FA”等字符串数组等转化为十进制数组

int array[32][32];

int a,b, n=0;

int result1;

char *str;

for(int i=0; i<32; i++)

for(int j=0; j<32; j++){

     str = str[i][j];

     if(str[0] >= ‘A’ && str[1] >=’A’){ //”AF”

        a = str[0] – ‘A’;

        b= str[1] – ‘A’;

        result1 = (a+10)*16+(b+10)*1;}

     else if(str[0] >= ‘A’ && str[1] <’A’){ //”A9”

        a = str[0] – ‘A’;

        b = ‘A’  – str[1] +1;

        result1 = (a+10)*16+b;}

     else if(str[0] < ‘A’ && str[1] >=’A’){ //”8B”

        a = ‘A’ – str[0]+1;

        b = str[1] – ‘A’;

        result1 = a*16+(b+10)*1;}

     else{                       //”87”

        a = ‘A’ – str[0]+1;

        b = ‘A’  – str[1] +1;

        result1 = a*16+b;}

     array[i][j] = reslut1;

     printf(“%5d”, array[i][j]);

     n++;

     if(n%32 = = 0) printf(“"n”); }

将这个矩阵数组在屏幕上显示:

#i nclude < afxwin.h >

#i nclude < afxext.h >

#i nclude < afxdisp.h >

#i nclude < afxdtctl.h >

DWORD color_;

HDC hMyDC = GetDC(NULL);

for(i=0; i<32; i++)

for(j=0; j<32; j++){

     color_ = array[i][j];

     color_ = color_*256*256 + color_*256+color_;

     SetPixel(hMyDC, j, i, color_); }

 

5.        将一个整型转化为一个字符串 _itoa

//将从位图信息头得到的图像宽度和高度显示出来

char buffer1[20], buffer2[20];

_itoa( width, buffer1, 10);

_itoa( height, buffer2, 10);

char str[80];

strcpy(str, “width=”);

strcat(str, buffer1);

strcat(str, “, hight=”;

strcat(str, buffer2);

AfxMesageBox(str, MB_OK, 0);

 

6.        当把二维数组地址用作参数传递,而又要此地址不断递增时,可以另外定义一个同类型指针,指向二维数组第一个元素的地址,把这个赋值放在循环外:

     unsigned char *p;

     p = &m_pImage[0][0];

   然后在循环中,可以p + m_count*4096;

 

7.        改变最近打开文档的个数

在InitInstance()中的LoadStdProfileSetting(8); //括号里是要设置的个数

8.        打开调色板对话框

CColorDialog dlg;

dlg.Domodal();

 

9.        如何添加工具栏,如何使用Slider?

在OnInitDialog()中添加:

CSliderCtrl *pSliderCtrl=(CSliderCtrl*)GetDlgItem(IDC_SLIDER1);

pSliderCtrl -> SetRange(0,255,TRUE); //设置滑动条的范围

pSliderCtrl -> SetPos(100); // 设置滑动条的初始位置

在Dlg类中响应WM_HSCROLL消息:

CSliderCtrl *pSliderCtrl=(CSliderCtrl*)GetDlgItem(IDC_SLIDER1);

m_nCur = pSliderCtrl - >GetPos(); //获得当前的位置值

 

10.     更改光标

:: SetCursor(:: LoadCursor(NULL, IDC_SIZEALL));

//如果是自己定义的光标资源,则要用MAKEINTRESOURCE 进行转化,例如:

:: SetCursor(:: LoadCursor(NULL, IDC_CURSOR_CUT));

 

11.     设置文本显示的一些函数

CDC dc(this); 

CPen pen(PS_SOLID, 2, #0000ff); //初始化一支笔

CBrush *pBush = CBrush :: FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));

dc.SelectObject(pBrush);

dc.SetTextColor(RGB(255,0 ,255));

dc.SetBKMode(TRANSPARENT); //将文本背景设置为透明

 

12.     将对话框中的图像拷贝到剪贴板

CWnd* pWnd = GetDlgItem(IDC_IMAGE_SELECT);

WINDOWPLACEMENT *winPlacement;

WinPlacement = new WINDOWPLACEMENT;

pWnd -> GetWindowPlacement(winPlacement); //获得一个控件的位置

CDC *dcTemp;

dcTemp= new CClientDC(FromHandle(m_hWnd));

CDC memDC;

memDC.CreateCompatibleDC(dcTemp); //创建一个兼容的DC

CBitmap bm;

CSize sz(lWidth, lHeight);

bm.CreateCompatilbleBitmap(dcTemp, sz.cx, sz.cy); //创建一个兼容的位图

CBitmap* oldbm = memDC.SelectObject(&bm);

memDC.BitBlt(0, 0, sz.cx, sz.cy, dcTemp, winPlacement ->rcNormalPosition.left,

            winPlacement ->rcNormalPosition.top, SRCCOPY);

pWnd -> OpenClipboard(); //打开剪贴板,不用pWnd->GetParent()->OpenClipard();

:: EmptyClipard();

:: SetClipardData(CF_BITMAP, bm.m_hObject); //粘贴到剪贴板

CloseClipard();

memDC.SelcetObject(oldbm);

delete dcTemp;

 

13.     VC里获取一个文件夹路径

BROWSEINFO bi;

TCHAR szDisplayName[MAX_PATH];

LPITEMIDLIST pidl;

LPMALLOC pMalloc = NULL;

ZeroMemory(&bi, sizeof(bi));

bi.hWndOwner = GetSafeHwnd();

bih.pszDisplayName = szDisplayName;

bi.lpszTitle = TEXT(“Please select a folder:”);

bi.ulFlags = BIF_RETURNONLYFSDIRS;

Pidl = SHBrowseForFolder(&bi);

if(pidl) {

      SHGetPathFromIDList(pidl, szDisplayName);

      sPath = szDisplayName;

      MessageBox(sPath); }

 

14.     如何设置密码输入时显示的是*号

#i nclude <iostream.h>

#i nclude <conio.h>

char a[8];

void main() {

int i=0;

Cout<<”请输入密码:”<<endl;

while(1) {

     a[i] = getch();

     if( i>=8 || a[i]= = 13)

        break;

     putch(‘*’);

     i++; }

cout<<endl<<a<<endl;

getch(); }

 

15.     设置菜单:可以使用CMenu:: EnableMenuItem()来设置菜单可用或禁用,但是在MFC中,要使该函数起作用,需要将CWnd :: m_bAutomenuEnable设置为FALSE.

16.     关闭子窗口

:: SendMessage(:: AfxGetMainWnd() -> m_hWnd, WM_COMMAND, ID_FILE_CLOSE,0);

获取主窗口的指针 CWinThread :: m_pMainWnd

调用AfxGetMainWnd()可实现


   继续上面的总结~! To making  it  count~!。。。。。。
 
1.        获取CMain类的指针

CMain* pApp = ((CMain*)AfxGetApp()->m_pMainWnd);

ASSERT_KINDOF(CMain, pAPP); //确保pAPP是CMain的类对象

2.        VC++如何获取应用程序的实例句柄

实例句柄保存在CWinApp m_hInstance中

HANDLE hInstance = AfxGetInstanceHandle();

3.        VC++怎样加载其他的应用程序 三个SDK函数WinExec, ShellExecute, CreateProcess.

①      WinExec最简单,前一个指定路径,后一个指定显示方式;

②      ShellExecute(null, null, _T(“1.txt”), NULL, _T(“c:""temp”), SW_SHOWNORMAL);

③      STARTUPINFO stinfo; //启动窗口的信息

PROCESSINFO proinfo; //进程的信息

CreateProcess(NULL,_T(“notepad.exe)”,NULL,NULL,FALSE,NORMAL_PRIORITY_CLASS,NULL,NULL,&stinfo,&proinfo);

 

4.        如何确定顶层菜单所占据的菜单行数:首先,计算主窗口的高度和客户区高度;其次,从主框窗口的高度中减去客户区、框边界以及标题的高度;最后,除以菜单栏的高度

CRect rc, rcClient;

GetWindowRect(rc);

GetClientRect(rcClient);

Int menuHeight;

menuHeight = (rc.Height() – rcClicent.Height()–

::GetSystemMetrics(SM_CYCAPTION) – :: GetSystemMetrics(SM_CY)*2))

-                                                                                                  / :: GetSystemMetrics(SM_CYMENU) ;

5.        响应下拉菜单的消息为

ON_CBN_SELECTDOK(ID_TOOL_ZOOM, OnSelectZoomed)

6.        设置工具栏的标题

m_wndTestBar.SetWindowText(“your toolbar title”);

 

7.        如何获得应用程序主窗口的指针

CWnd pMainWnd = AfxGetApp() ->m_pMainWnd;

CMain *pMain = ((CMain*)pMainWnd;

CRect rect;

CWnd* pParent = AfxGetApp()->GetMainWnd();

pParent ->GetWindowRect(&rect); //得到应用程序窗口矩形

//移到窗口

pParent -> MoveWindow(rect.left, rect.top, rect.Width()+1,rect.Height()+1,TRUE);

8.        获得获得子窗口

CMDIChildWnd* pChild = (CMDIChildWnd*)GetActive();

//或:CMDIChildWnd* pChild=MDIGetActive();

9.        获得活动子窗口的活动视图

CMyView* pView = (CMyView*)pChild->GetActiveView();

获取当前窗口的指针

CWnd :: GetForegoundWindow();

10.     从句柄转换到指针

HWND hwnd;

hwnd = :: FindWindow(NULL, “TEST”);

CWnd* pWnd = FromHandle(hwnd);

11.     怎样改变进度条控件的颜色,发送消息

m_progress.SendMessage(PBM_SETBKCOLOR, 0, #ff0000); //背景色

m_progress.SendMessage(PBM_SETBARCOLOR, 0, #00ff00); //前景色

12.     定义char num[10];

        sprintf(num, “%d”, calnum); //格式化数字

        char unit[]=”矩形”;

        sprintf(num, “%s”, unit); //格式化字符串

13.     改变字符串的显示字体和大小

CFont font;

font.CreatePointFont(300, “华文行楷”,NULL);

CFont *pOldFont=dc.SelectObject(&font);

dc.SelectObject(pOldFont);

 

14.     将路径中的单’"’变为’""’

CMyDoc *pDoc=GetDocument();

CString reportPath = pDoc -> strPathName;

int lentemp = reportPath.GetLength();

reportPath = reportPath.Left(lentemp-4);

int lenpath = reportPath.GetLength();

for(int i=0; i<lenpath-1; ) {

     if(reportpath.GetAt(i) = = ‘""’) {

         reportpath.Insert(i, ‘""’);

         i+=2; }

     i++; }

 

15.     获取屏幕分辨率

HDC hSrcDC;

hSrcDC = ::GetDC(AfxGetApp() -> m_pMainWnd->GetSafeHwnd());

int xSrc, ySrc;

xSrc = GetDeviceCaps(hSrcDC, HORIRES); //水平分辨率

ySrc = GetDeviceCaps(hSrcDC, VERTRES); //垂直分辨率

 

16.     让Edit控件响应回车键:利用获取消息来完成,调用虚函数

PreTranslateMessage(MSG* pMsg) {

   If( pMsg ->message = = WM_KEYDOWN) {

      switch(pMsg -> wParam) {

         case VK_RETURN:

            GetDlgItem(IDC_BTN_INPUT)->SendMessage(BM_CLICK, 0, 0);

            return TRUE; } }    }

17.     改变对话框的背景色:在InitInstance()中加入

SetDialogBKColor(#a0b4dc, #ff0000); //后面是字体颜色

18.     让指定的矩形框重画 InvalidateRect(&rect, TRUE);

19.     怎样选择所选的List当前位置

int iTem;

POSITION pos=m_findCtrl.GetFirstSelectedItemPosition();

if(pos = = 0) {

 MessageBox(“请选择需要删除的记录”);

 return; }

else {

iTem = m_findCtrl.GetNextSelectedItem(pos); }

 //删除List中的某行

 m_findCtrl.DeleteItem(iTem);

m_findCtrl.Update(iTem);

 

20.     动态创建控件

CEdit m_edit;

CRect rect(0,0,100,200);

M_edit.Create(WS_CHILD | ES_AUTOHCROLL | WS_BORDER, rect, this, ID_EDIT_1);

21.     列表控件的应用

CListCtrl* m_list;

CRect rect_list;

this->GetCientRect(&rect_list);

rect_list.top + =100;

m_list -> Create(WS_CHILD | LVS_REPORT | WS_BORDER | LVS_SINGLESEL, rect_list, this, ID_TABLIST);

this ->m_list->ModifyStyle(LVS_EDITABELS,0L); //禁止标题编辑

m_list->ModifyStyle(0L ,LVS_REPORT); //设置为Report类型

m_list->ModifyStyle(0L, LVS_SHOWSELALWAYS); //始终高亮显示被选中的表项

m_list->ModifyStyle(0L,LVS_NOSORTHEADER); //禁止标题编辑

m_list->SetBkColor(#00c8c8); //设置背景颜色

m_list->SetTextBkColor(#00c8c8); //设置文本背景颜色

m_list->ModifyStyle(LVS_OWNERDRAWFIXED,0L);

m_list->SetExtendedStyle(LVS_EX_FULLROWSELET //整行选中

                     | LVS_EX_HEADERDARGDROP //允许整列拖动

                     | LVS_EX_GRIDLINES   //画出网格线

                     | LVS_EX_FLATSB); // 扁平风格的滚动条

22.     取得当前获得焦点的窗口句柄

HWND hwnd = ::GetFocus();

int iID = :: GetDlgCtrlID(hwnd); // 根据句柄取得其资源符号

 

23.     修改控件的字体

CFont m_font;

m_font.CreateFont(-12,0,0,0,400,FALSE,FALSE,0,GB2312_SHARSET,OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, VARIABLE_PITCH | FF_, “楷体_GB2312”);

//为想改变字体的控件改变

m_editPh.SetFont(&m_font, true);


1.        如何暂停主线程直到第二个线程的终止?

void CMyTestDialog ::PeekMessageLoop() {

      MSG msg;

     while ( PeekMessage(&msg, NULL, NULL, NULL, NULL,NULL, PM_REMOVE)) {

                   TranslateMessage(&msg);

                   DispatchMessage(&msg); } }

Void CMyTestDialog :: WaitForThreadToTerminate( HANDLE hThread) {

          //将指示哪个线程需要等待并作进一步处理

      DWORD dwRet;

      Do {

           dwRet = :: MsgWaitForMultipleObject(1, &hThread, FALSE, INFINITE, QS_ALLINPUT);

           if(dwRef != WAIT_OBJET_0) {

                 PeekMessageLoop();   }

         }while ( (dwRet != WAIT_OBJET_0) && (dwRet != WAIT_FAILED));

//示例代码:假设对话框上有一个按钮,当点击按钮时,开始启动第二个线程,等到第

//二个线程完成后,我们再继续主线程:

void CMyTestDialog :: OnButton1() {

      m_pUpdateThread = AfxBeginThread(UpdateDeviceContent, (LPVOID)this);

      if(m_pUpdateThread) {

                WaitForThreadToTerminate(m_pUpdateThread->m_hThread); }

      //这里可以加入自己的执行代码

     Do whatever you want after the action is finished. } 

2.        改变列表框表头的颜色和字体,发送一个HDM_GETITEM消息

void CHeaderCtrlEx :: DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) {

     ASSERT(lpDrawItemStruct ->ctlType = =ODT_HEADER);

     HDITEM hdi;

     TCHAR lpBuffer[256];

     Hdi.mask = HDI_TEXT;

     Hdi.pszText = lpBuffer;

     Hdi.uhTextMax = 256;

     GetItem(lpDrawItemStruct->itemID,&hdi);

//画按钮框

:: DrawControl(lpDrawItemStruct->hdc, &lpDrawItemStruct->rcItem, DFC_BUTTOON, DFCS_BUTTONPUSH);

COLORREF crOldColor = :: SetTextColor(lpDrawItemStruct->hdc, #ffff00);

:: DrawText(lpDrawItemStruct->hdc, lpBuffer, strlen(lpBuffer), &lpDrawItemStruct->rcItem, DT_SINGLELINE | DT_VCENTER | DT_CENTER);

:: SetTextColor(lpDrawItemStruct->hdc, crOldColor); } 

3.        修改标题栏中“无标题-title”

①      修改“无标题”部分,重载文档中的虚函数SetTitle,加入:

CDocument:: SetTitle(”your title”);

②      修改后半部分:将字符串资源中的IDR_MAIN修改为

我的程序"n"nChange"n"n"nChangeTitle.Document"nChange Document

或者:在程序的任何地方调用如下语句:

(AfxGetMainWnd()) -> SetWindowText(“your title”);

③      除去标题中间的”-“,可以通过重载CFramWnd类的OnUpdateTitle函数,这个函数在VC提供的帮助文件中找不到,必须手工添加:

virtual void OnUpdateTitle(BOOL NaDa);

void CMain :: OnUpdateTitle(BOOL NaDa) {

CString csAppName;

csAppName.Format(AFX_IDS_APP_TITLE);

SetWindowText(csAppName); }

//此时显示的结果只有字符串资源AFX_IDS_APP_TITLE 所定义的字符串

★      另一种方法是在CMain的PreCreateWindow函数中修改的窗口风格:

BOOL CMain :: PreCreateWindow(CREATESTRUCT &cs) {

   cs.style &= ~ (LONG)FWS_ADDTOTITLE;

   return CWnd :: PreCreateWindow(cs); }

//使用此方法,窗口的标题只显示IDR_MAIN字符串中第一个"n之前的部分。

 

((CMainFram*)AfxGetMainWnd())->SetWindowText("****");     放在App类的InitInstance()函数里面

 

 

4. const的一些用法

    int a=0;

    const int* b=&a; [1]   int const *b=&a;[2]   const int* const b=&a; [3]

    const char *p=”const”; [1] char const *p=”const”; [2] char const p=”const”; [4]

    const char* const p=”const”; [4]

 

    int a=0;

   const int &b=a; [1]   int const &b=a; [2]   int & const b=a; [3] const int & const b=a; [4]

①      如果const位于星号左侧,则const用来修改指针所指向的变量,即指针指向的为不可变的;

②      如果const位于星号右侧,const就是修饰指针本身,即指针本身是不可变的;

③      [3]中指针本身是不可变的,而指针所指向的内容是可变的,这种情况下不能对指针本身进行更改操作,如b++是错误的;

④      [4]中指针本身和指向的内容均为常量

5. const作为参数用法

void fun0( const A *a) 在函数体中,按照const所修饰的部分进行常量化,如形参为const A* a,则不能对传递进来的指针的内容进行改变,保护了原指针所指向的内容;

void fun1(const A& a) 形参为const A& a,则不能对传递进来的引用对象进行改变,保护了原对象的属性。[注:参数const通常用于参数为指针或引用的情况]

const修饰返回值: const A fun2(); const A* fun3()

一般用const修饰返回值为对象本身(非引用和指针)的情况多用于二目操作符重载函数,并产生新的对象的时候。

[总结]: 一般情况下,函数的返回值为某个对象时,如果将其声明为const时,多用于操作符的重载。通常,不建议用const修饰函数的返回值类型为某个对象或对某个对象引用的情况。

6. 类成员函数中const的使用:一般放在函数体后void fun() const; 如果一个成员函数不会修改数据成员,那么最好将其声明为const,因为const成员函数中不允许对数据成员进行修改,如果修改,编译器会报错,大大提高了程序的健壮性。

7. 使用const的一些suggestioins:

① 要大胆地使用const,这将给你带来无尽的益处,但前提是你必须搞清楚原委;

② 在参数中使用const应使用引用或指针,而不是一般的对象实例;

③ 要避免最一般的赋值操作错误,如将const变量赋值;

④ 不要轻易地将函数的返回类型定为cosnt;

⑤      除了重载操作符外一般不要将返回值类型定为某个对象的const引用 

8. 让应用程序只运行一个实例: 在App的InitInstance添加如下代码:

     HANDLE hSem = CreateSemaphore(NULL, 1, 1, m_pszAppName);

     if(GetLastError() = = ERROR_ALREADY_EXISTS) { //信号量存在,则有一个在运行

         CloseHandle(hSem); //关闭信号量句柄

         // 寻找先前的实例窗口

         HWND hWndPrevious = ::GetWindow(::GetDesktopWindow(), GW_CHILD);

         While(:: IsWindow(hWndPrevious)) { //检查窗口是否有预设的标记

           if(::GetProp(hWndPrevious,m_pszAppName)) { //有,则寻找主窗口

               if(:: IsIconic(hWndPrevious)) { //窗口最小化,则恢复其大小

                   ::SetForegroundWindow(hWndPrevious); //将主窗口激活

                   ::SetForgoundWindow(::GetLastActivePopup(hWndPrevious));

                   //将主窗口激活

                   ::ShowWindow(hWndPrevious, SW_NORMAL);

                   reurn FALSE; } //退出本实例

           hWndPrevious = :: GetWindow(hWndPrevious, GW_HWNDNEXT); //继续找 }

     AfxMessageBox(“only one application program can run!”);

     return FALSE; } }

1.获取本机的IP地址

#i nclude <stdio.h>

#i nclude <winsock2.h>

#pragma comment (lib, “ws2_32.lib”)

Void CheckIP() {

   WSADATA wsadata;

Char name[155];

Char *ip;

PHOSTENT hostinfo;

If (WSAStartUp( MAKEWORD(2,0), &wsadate) = = 0) {

     If ( gethostname( name, sizeof(name)) = = 0) {

         If((hostinfo = gethostbyname(name)) != NULL) {//获得IP的函数

             Ip = inet_ntoa(*(struct in_addr*)*hostinfo -> h_addr_list);

             Printf*”%s"n”, ip); } }

WSACleanup(); }    }

 

2. CWnd:: SetDlgItemInt(); 被对话框设定一个由字符串表示的整型值。

   CSemaphore ---à CSyncObject------àCObject

     在一个进程或多个进程中允许访问一种资源的允许线程数,CSemaphore对象维持当前获取一种指定资源的线程个数。当计数大于0时,Semaphore对象的状态是有信号状态;典型应用是用Semaphore去限制使用一种资源的线程个数。用WaitforSingleObject等待有信号状态,返回时则减少对Semaphore的计数。

3. 得到计算机所有驱动函数GetAllDriverList()

     CString tmp = _T(“A:""”), dir;

     for(int i=1; i<=25; i++) {

          dir = CString(‘A’+i)+ _T(“:""”);

          if(GetDriveType(dir.GetBuffer(0)) = = DRIVE_NO_ROOT_DIR) continue;

          tmp += “;” + dir; }

     return tmp;

4. 打开对话框,选择文件路径函数 OnBrowse()

BROWSEINFO bi;

char dispname[MAX_PATH], path[MAX_PATH];

ITEMIDLIST    *pidl;

bi.hwndOwner = m_hWnd;

bi.pidlRoot = 0;

bi.pszDisplayName = dispname;

bi.ulFlags = BIF_RETUREONLYFSDIRS | BIF_EDITBOX | BIF_DONTGOBELOWDOMAIN;

bi.lpfn = 0;

bi.lParam = 0;

bi.iImage = 0;

if(pidl = SHBrowseForFolder(&bi)) { //显示一个使用用户可以选择的文件打开对话框

 SHGetPathFromIDList(pidl, path); //把一个item identifier list转化为一个文件系统路径

 m_folder = CString(path);

 if(m_folder.IsEmpty() )   m_folder = GetAllDirverList();

 UpdateData(FALSE); }

SHGetFileInfo(); 返回文件系统中对象的信息,比如文件、folder、路径、驱动器

 

5. 如何使用CImageList 

CImageList m_iImageList;

m_iImageList.Create(24,24,TRUE,1,0);

HICON hIcon = NULL;

hIcon = (HICON)::LoadImage(::AfxGetInstanceHandle(), MAKEINTRESOURCE(IDI_KEBIAO0, IMAGE_ICON,24,24,0);

m_iImageList.Add(hIcon);

m_FileTree.SetImageList(&m_iImageList, TVSIL_NORMAL); //m_FileTree为TreeList控件

//或者这样来创建:

m_imageList.DeleteImageList();

m_image.Create(16,16,ILC_COLORDDB,1,100);

m_listCtrl.SetImageList(&m_iImageList, LVSIL_SMALL);

6. 遍历一个文件夹的文件

OnFindFile(WPARAM wParam, LPARAM lParam) {

 CString strFilePath = *((CString*)wParam);

 if(strFilePath.Right(1) != “""”) {

     strFilePath +=”""”; }

strFilePath += “*.*”;

CFileFind   finder;

CString strFileName;

BOOL isHave = finder.FindFile(strFilePath);

while(isHave) {

     isHave = finder.FindNextFile();

     if(!finder.IsDirectory() && !finder.IsDots()) {

         strFileName = finder.GetFilePath();

         :: PostMessage((HWND)(GetMainWnd()->GetSafeHWnd()), WM_DISPLAY, (WPARAM)&strFileName, NULL); } }

finder.Close();   }

7. 如何来启动这个查找线程

新建一个类派生于CWinThread;CFindFileThread *pFindFileThread;

pFindFileThread = (CFindFileThread*)AfxBeginThread(RUNTIME_CLASS(CFindFileThread);

pFindFileThread -> PostThreadMessage(WM_FINDFILE, (WPARAM)&strFilePath,NULL);

 

8. 找到一个则发送消息WM_DISPLAY,并把文件中全路径作为参数返回

     获取一个文件的信息 OnDisplay(WPARAM wParam, LPARAM lParam) {

     count++; //统计文件个数

     CString strFileName = *((CString*)wParam);

     CFileStatus status;

     C: GetStatus(strFileName, status);

     CString unit = “Byte”;

     float flen = (float)status.m_size;

     if(flen>1024) {

           flen /= 1024;

           if(flen < 1024)   unit = “KB”;

           else {

                flen /= 1024;

                unit = “MB”; } }

      CString size;

      size.Format(“%1.2f”, flen);

      int pos = strFileName.ReverseFind(‘""’);

      SHFILEINFO sfi; //文件信息结构体

      if(:: SHGetFileInfo(strFileName, FILE_ATTRIBUTE_NORMAL, &sfi,

         Sizeof(SHFILEINFO), SHGFI_USEFILEATTRIBUTES |

          SHGFI_DISPLAYNAME | SHGFI_TYPENAME | SHGFI_ICON

              | SHGFI_SMALLICON)) {

            m_imgList.Add(sfi.hIcon);

            m_filelist.InsertItem(count-1, sfi.szDisplayName, count-1);

            m_filelist.SetItemText(count-1, 1, strFileName, Mid(0,pos));

          m_filelist.SetItemText(count-1, 2, (size+unit));

          m_filelist.SetItemText(count-1, 3, sfi.szTypeName); }


     m_filelist.Update(count-1); }
 

9. 在图片中隐藏信息的做法:加社会图片文件为c:"s.jpg, 文字为d:"w.txt, 在命令行方式窗口中输入命令   COPY /B C:"s.jpg + d:"w.txt   c:"d.jpg

 

10. 获得应用程序所在路径

char szCurPath[_MAX_PATH];

HINSTANCE hInst = NULL;

GetMoudleFileName( hInst, szCurPath, _MAX_PATH); //获得应用程序所在路径

char *p = szCurPath;

while( strchr(p, ‘""’)) {

      p= strchr( p, ‘""’);

      p++; }

*p = ‘"0’;


ShellExecute(NULL, NULL, _T(“Your.exe”), NULL, _T(szCurPath), SW_SHOWNORMAL);
 
总结问题的解决方法,有助于获得更多的实战经验,不断地积累,在编程方面就会有长足的进步~!

学习的过程是一个不断积累的过程,只有学习的时间累积到一定的程度,才能发生质的提高。。。

 

 

 

(1) 如何通过代码获得应用程序主窗口的 指针?
主窗口的 指针保存在CWinThread::m_pMainWnd中,调用AfxGetMainWnd实现。
AfxGetMainWnd() ->ShowWindow(SW_SHOWMAXMIZED)
//使程序最大化.


(2) 确定应用程序的路径
Use GetModuleFileName 获得应用程序的路径,然后去掉可执行文件名。
Example:
TCHAR
exeFullPath[MAX_PATH] // MAX_PATH在API中定义了吧,好象是
128
GetModuleFileName(NULL,exeFullPath,MAX_PATH)
(3) 如何在程序中获得其他程序的 图标?
两种方法:
(1) SDK函数 SHGetFileInfo 或使用 ExtractIcon获得图标资源的 handle,
(2) SDK函数 SHGetFileInfo 获得有关文件的很多信息,如大小图标,属性, 类型等.
Example(1):
在程序窗口左上角显示 NotePad图标.
void CSampleView:
OnDraw(CDC * pDC)
{
if( :: SHGetFileInfo(_T("c:""pwin95""notepad.exe"),0,
&stFileInfo,sizeof(stFileInfo),SHGFI_ICON))
{
pDC ->DrawIcon(10,10,stFileInfo.hIcon)
}
}
Example(2):同样功能,Use ExtractIcon Function
void CSampleView:: OnDraw(CDC *pDC)
{
HICON hIcon=:: ExtractIcon(AfxGetInstanceHandle(),_T
("NotePad.exe"),0)
if (hIcon &&hIcon!=(HICON)-1)
pDC->DrawIcon(10,10,hIcon)
}
    说明: 获得notepad.exe的路径正规上来说用GetWindowsDirectory函数得到, 如果是调用 win95下的画笔,应该用访问注册表的方法获得其路径,要作成一个比较考究的程序,考虑应该全面点.

 


(4) 获得各种目录信息
Windows目录: Use "GetWindowsDirectory"
Windows下的system目录: Use "GetSystemDirectory"
temp目录: Use "GetTempPath"
当前目录: Use "GetCurrentDirectory"
请注意前两个函数的第一个参数为目录变量名,后一个为缓冲区后两个相反.


(5) 如何自定义消息
1) 手工定义消息,可以这么写
#define WM_MY_MESSAGE(WM_USER+100),
MS 推荐的至少是 WM_USER+100
(2)写消息处理函数,用
WPARAM,LPARAM返回LRESULT.
LRESULT CMainFrame::OnMyMessage(WPARAM wparam,LPARAM lParam)
{
temp目录: Use "GetTempPath"
//加入你的处理函数 irectory"
}

(6) 如何改变窗口的图标?
向窗口发送 WM_SECTION消息。
Example:
HICON hIcon=AfxGetApp() ->LoadIcon(IDI_ICON)
ASSERT(hIcon)
AfxGetMainWnd() ->SendMessage(WM_SECTION,TRUE,(LPARAM)hIcon)


(7) 如何改变窗口的缺省风格?
重载 CWnd:: PreCreateWindow 并修改CREATESTRUCT结构来指定窗口风格和其他创建信息.
Example: Delete "Max" Button and Set Original
Window's Position and Size
BOOL CMainFrame:: PreCreateWindow
(CREATESTRUCT &cs)
{
cs.style &=~WS_MAXINIZEMOX
cs.x=cs.y=0
cs.cx=GetSystemMetrics(SM_CXSCREEN/2)
cs.cy=GetSystemMetrics(SM_CYSCREEN/2)
return CMDIFramewnd ::PreCreateWindow(cs)
}

(8) 如何将窗口居中显示?
Call Function CWnd::
Center Windows
Example(1):
Center Window( ) //Relative to it's parent
// Relative
to Screen
Example(2):
Center Window(CWnd:: GetDesktopWindow( ))
//Relative to
Application's MainWindow
AfxGetMainWnd( ) ->
Center Window( )


(9) 如何让窗口和 MDI窗口一启动就最大化和最小化?
先说窗口。
在 InitStance 函数中设定 m_nCmdShow的取值.
m_nCmdShow=SW_SHOWMAXMIZED //最大化
m_nCmdShow=SW_SHOWMINMIZED //最小化
m_nCmdShow=SW_SHOWNORMAL //正常方式
MDI窗口:
如果是创建新的应用程序,可以用MFC AppWizard 的Advanced 按钮并在MDI子窗口风格组中检测最大化或最小化还可以重载 MDI Window 的PreCreateWindow函数,设置WS_MAXMIZE or WS_MINMIZE
如果从 CMDIChildWnd派生,调用 OnInitialUpdate函数中的 CWnd::Show Window来指定 MDI Child Window的风格。

(10) 如何限制窗口的大小?
也就是 FixedDialog形式。 Windows发送 WM_GETMAXMININFO消息来跟踪, 响应它,在 OnGetMAXMININFO 中写代码:

(11) 如何使窗口不可见?
很简单,用SW_HIDE 隐藏窗口,可以结合 FindWindow,ShowWindow控制.

(12) 如何创建一个字回绕的CEditView
重 载CWnd : : PreCreateWindow和修改CREATESTRUCT结构,关闭CEditView对象的ES_AUTOHSCROLL和WS_HSCROLL 风格位, 由于CEditView : : PreCreateWindow显示设置cs. style,调用基类函数后要修改cs . style。
BOOL CSampleEDitView : : PreCreateWindow (CREATESTRUCT&cs)
{
//First call basse class function .
BOOL bResutl =CEditView : : PreCreateWindow (cs)
// Now specify the new window style .
cs.style &= ~ (ES_AUTOHSCROLL |WS_HSCROLL)
return bResult
}

(13) 如何使程序保持极小状态?
这么办: 在恢复程序窗体大小时,Windows会发送WM_QUERY-OPEN消息,用 ClassWizard设置成员函数
OnQueryOpen() ,add following code:
Bool CMainFrame:: OnQueryOpen( )
{
Return false
}

(14) 移动窗口
调用CWnd : : SetWindowPos并指定SWP_NOSIZE标志。目的位置与父窗口有关(顶层窗口与屏幕有关)。调用CWnd : : MoveWindow时必须要指定窗口的大小。
//Move window to positoin 100 , 100 of its parent window .
SetWindowPos (NULL, 100 , 100 , 0 , 0 , SWP_NOSIZE |SWP_NOAORDER)

(15) 通用控件的显示窗口
MFC 提供了几个CView派生的视窗类, 封装了通用控件的功能,但仍然使用工作框文档显示窗口体系结构:CEditView封装了编辑控件,CTreeView保持了树列表控 件,CListView封装了列表显示窗口控件,CRichEditView可以处理多种编辑控件。

(16) 重置窗口的大小
调用CWnd: : SetWindowPos并指定SWP_NOMOVE标志, 也可调用CWnd : : MoveWindow 但必须指定窗口的位置。
// Get the size of the window .
Crect reWindow
GetWindowRect (reWindow )
//Make the window twice as wide and twice as tall .
SetWindowPos (NULL , 0 , 0 , reWindow . Width ( ) *2,
reWindow . Height () * 2,
SWP_NOMOVE |SWP_NOZORDER )

(17) 如何单击除了窗口标题栏以外的区域使窗口移动
当 窗口需要确定鼠标位置时Windows向窗口发送WM_NCHITTEST信息,可以处理该信息使Windows认为鼠标在窗口标题上。对于对话框和基于 对话的应用程序,可以使用ClassWizard处理该信息并调用基类函数, 如果函数返回HTCLIENT 则表明鼠标在客房区域,返回HTCAPTION表明鼠标在Windows的标题栏中。
UINT CSampleDialog : : OnNcHitTest (Cpoint point )
{
UINT nHitTest =Cdialog: : OnNcHitTest (point )
return (nHitTest = =HTCLIENT)? HTCAPTION : nHitTest
}
上述技术有两点不利之处,
其一是在窗口的客户区域双击时,窗口将极大;
其二, 它不适合包含几个视窗的主框窗口。
还有一种方法,当用户按下鼠标左键使主框窗口认为鼠标在其窗口标题上,使用ClassWizard在视窗中处理WM_LBUTTODOWN信息并向主框窗口发送一个WM_NCLBUTTONDOWN信息和一个单击测试HTCAPTION。
void CSampleView : : OnLButtonDown (UINT nFlags , Cpoint point
)
{
CView : : OnLButtonDow (nFlags , pont )
//Fool frame window into thinking somene clicked
on
its caption bar .
GetParentFrame ( ) —> PostMessage (
WM_NCLBUTTONDOWN ,
HTCAPTION , MAKELPARAM (poitn .x , point .y) )
}
该技术也适用于对话框和基于对的应用程序,只是不必调用
CWnd: :GetParentFrame 。
void CSampleDialog : : OnLbuttonDown (UINT nFlags, Cpoint point )
{
Cdialog : : OnLButtonDow (nFlags, goint )
//Fool dialog into thinking simeone clicked on its
caption bar .
PostMessage (WM_NCLBUTTONDOWN , HTCAPTION , MAKELPARM (point.x
, point. y
) )
}

(18) 如何改变视窗的背景颜色
Windows向窗口发送一个WM_ERASEBKGND消息通知该窗口擦除背景,可以使用ClassWizard重载该消息的缺省处理程序来擦除背景(实际是画),并返回TRUE以防止Windows擦除窗口。
//Paint area that needs to be erased.
BOOL CSampleView : : OnEraseBkgnd (CDC* pDC)
{
// Create a pruple brush.
CBrush Brush (RGB (128 , 0 , 128) )
// Select the brush into the device context .
CBrush* pOldBrush = pDC—>SelcetObject (&brush)
// Get the area that needs to be erased .
CRect reClip
pDC—>GetCilpBox (&rcClip)
//Paint the area.
pDC—> PatBlt (rcClip.left , rcClip.top , rcClip.Width ( ) , rcClip.Height( ) , PATCOPY )
//Unselect brush out of device context .
pDC—>SelectObject (pOldBrush )
// Return nonzero to half fruther processing .
return TRUE
}

(19) 如何改变窗口标题
调用CWnd : : SetWindowText可以改变任何窗口(包括控件)的标题。
//Set title for application's main frame window .
AfxGetMainWnd ( ) —> SetWindowText (_T("Application title") )
//Set title for View's MDI child frame window .
GetParentFrame ( ) —> SetWindowText ("_T ("MDI Child Frame new title")
)
//Set title for dialog's push button control.
GetDigitem (IDC_BUTTON) —> SetWindowText (_T ("Button new title ") )
如 果需要经常修改窗口的标题(注:控件也是窗口),应该考虑使用半文档化的函数AfxSetWindowText。该函数在AFXPRIV.H中说明,在 WINUTIL.CPP中实现,在联机帮助中找不到它,它在AFXPRIV.H中半文档化, 在以后发行的MFC中将文档化。
AfxSetWindowText的实现如下:
voik AFXAPI AfxSetWindowText (HWND hWndCtrl , LPCTSTR IpszNew )
{
itn nNewLen= Istrlen (Ipaznew)
TCHAR szOld [256]
//fast check to see if text really changes (reduces
flash in the
controls )
if (nNewLen >_contof (szOld)
|| : : GetWindowText (hWndCrtl, szOld , _countof (szOld) !=nNewLen
|| Istrcmp (szOld , IpszNew)! = 0
{
//change it
: : SetWindowText(hWndCtrl , IpszNew )
}
}

(20) 如何防止主框窗口在其说明中显示活动的文档名
创建主框窗口和MDI子窗口进通常具有FWS_ADDTOTITLE风格位,如果不希望在说明中自动添加文档名, 必须禁止该风格位, 可以使用ClassWizard重置
CWnd: : PreCreateWindow并关闭FWS_ADDTOTITLE风格。
BOOL CMainFrame : : PreCreateWindow (CREATESTRUCT&cs)
{
//Turn off FWS_ADDTOTITLE in main frame .
cs.styel & = ~FWS_ADDTOTITLE  
return CMDIFrameWnd : : PreCreateWindow (cs )
}
关闭MDI子窗口的FWS _ADDTOTITLE风格将创建一个具有空标题的窗口,可以调用CWnd: : SetWindowText来设置标题。记住自己设置标题时要遵循接口风格指南。

(21) 如何获取有关窗口正在处理的当前消息的信息
调用CWnd: : GetCurrentMessage可以获取一个MSG指针。例如,可以使用ClassWizard将几个菜单项处理程序映射到一个函数中,然后调用GetCurrentMessage来确定所选中的菜单项。
viod CMainFrame : : OnCommmonMenuHandler ( )
{
//Display selected menu item in debug window .
TRACE ("Menu item %u was selected . "n" ,

(22) 如何在代码中获取工具条和状态条的指针
缺 省时, 工作框创建状态条和工具条时将它们作为主框窗口的子窗口,状态条有一个AFX_IDW_STATUS_BAR标识符,工具条有一个 AFX_IDW_TOOLBAR标识符,下例说明了如何通过一起调用CWnd: : GetDescendantWindow和AfxGetMainWnd来获取这些子窗口的指针:
//Get pointer to status bar .
CStatusBar * pStatusBar = (CStatusBar *) AfxGetMainWnd ( )
—> GetDescendantWindow(AFX_IDW_STUTUS_BAR)
//Get pointer to toolbar .
CToolBar * pToolBar = (CToolBar * ) AfxGetMainWnd ( )
—> GetDescendantWindow(AFX_IDW_TOOLBAR)

(23) 如何使能和禁止工具条的工具提示
如 果设置了CBRS_TOOLTIPS风格位,工具条将显示工具提示,要使能或者禁止工具提示,需要设置或者清除该风格位。下例通过调用 CControlBar : : GetBarStyle和CControlBar : : SetBarStyle建立一个完成此功能的成员函数:
void CMainFrame : : EnableToolTips ( BOOL bDisplayTips )
{
ASSERT_VALID (m_wndToolBar)
DWORD dwStyle = m _wndToolBar.GetBarStyle ( )
if (bDisplayTips) dwStyle |=CBRS_TOOLTIPS
else
dwStyle & = ~CBRS_TOOLTIPS
m_wndToolBar.SetBarStyle (dwStyle )
}

(24) 如何创建一个不规则形状的窗口
可以使用新的SDK函数SetWindowRgn。该函数将绘画和鼠标消息限定在窗口的一个指定的区域,实际上使窗口成为指定的不规则形状。 使用AppWizard创建一个基于对的应用程序并使用资源编辑器从主对话资源中删除所在的缺省控件、标题以及边界。
给对话类增加一个CRgn数据成员,以后要使用该数据成员建立窗口区域。
Class CRoundDlg : public CDialog
{

private :
Crgn m_rgn : // window region

}
修改OnInitDialog函数建立一个椭圆区域并调用SetWindowRgn将该区域分配给窗口:
BOOL CRoundDlg : : OnInitDialog ( )
{
CDialog : : OnInitDialog ( )
//Get size of dialog .
CRect rcDialog
GetClientRect (rcDialog )
// Create region and assign to window .
m_rgn . CreateEllipticRgn (0 , 0 , rcDialog.Width( ) , rcDialog.Height ( ) )
SetWindowRgn (GetSafeHwnd ( ) , (HRGN) m_ rgn ,TRUE )
return TRUE
}
通过建立区域和调用SetWindowRgn,已经建立一个不规则形状的窗口,下面的例子程序是修改OnPaint函数使窗口形状看起来象一个球形体。
voik CRoundDlg : : OnPaint ( )
{
CPaintDC de (this) // device context for painting
.
//draw ellipse with out any border
dc. SelecStockObject (NULL_PEN)
//get the RGB colour components of the sphere color
COLORREF color= RGB( 0 , 0 , 255)
BYTE byRed =GetRValue (color)
BYTE byGreen = GetGValue (color)
BYTE byBlue = GetBValue (color)
// get the size of the view window
Crect rect
GetClientRect (rect)
// get minimun number of units
int nUnits =min (rect.right , rect.bottom )
//calculate he horiaontal and vertical step size
float fltStepHorz = (float) rect.right /nUnits
float fltStepVert = (float) rect.bottom /nUnits
int nEllipse = nUnits/3 // calculate how many to
draw
int nIndex
// current ellipse that is being draw
CBrush brush
// bursh used for ellipse fill color
CBrush *pBrushOld // previous
brush that was selected into dc
//draw ellipse , gradually moving towards upper-right
corner
for (nIndex = 0 nIndes < + nEllipse nIndes++)
{
//creat solid brush
brush . CreatSolidBrush (RGB ( ( (nIndex*byRed ) /nEllipse ).
( ( nIndex * byGreen ) /nEllipse ), ( (nIndex * byBlue)
/nEllipse ) ) )
//select brush into dc
pBrushOld= dc .SelectObject (&brhsh)
//draw ellipse
dc .Ellipse ( (int) fltStepHorz * 2, (int) fltStepVert * nIndex ,
rect. right -( (int) fltStepHorz * nIndex )+ 1,
rect . bottom -( (int) fltStepVert * (nIndex *2) ) +1)
//delete the brush
brush.DelecteObject ( )
}
}
最后,处理WM_NCHITTEST消息,使当击打窗口的任何位置时能移动窗口。
UINT CRoundDlg : : OnNchitTest (Cpoint point )
{
//Let user move window by clickign anywhere on thewindow .
UINT nHitTest = CDialog : : OnNcHitTest (point)
rerurn (nHitTest = = HTCLIENT)? HTCAPTION: nHitTest
}

(25) 如何获取应用程序的 实例句柄?
应用程序的实例句柄保存在CWinApp m_hInstance 中,可以这么调用AfxGetInstancdHandle获得句柄.
Example: HANDLE hInstance=AfxGetInstanceHandle()

(26) 如何编程结束应用程序?
这是个很简单又是编程中经常要遇到的问题.
向窗口发送 WM_CLOSE消息,调用 CWnd::OnClose成员函数.允许对用户提示是否保存修改过的数据.
Example: AfxGetMainWindow()->SendMessage(WM_CLOSE)
还可以创建一个自定义的函数 Terminate Window
void Terminate Window(LPCSTR pCaption)
{
CWnd *pWnd=Cwnd::FindWindow(NULL,pCaption)
if (pWnd)
pWnd ->SendMessage(WM_CLOSE)
}
    说 明: FindWindow函数不是提倡的做法,因为它无法处理标题栏自动改变,比如我们要检测 Notepad是不是已运行而事先不知道Notepad的标题栏,这时FindWindow就无能为力了,可以通过枚举 windows任务列表的办法来实现。在机械出版社"Windows 95 API开发人员指南"一书有比较详细的介绍,这里就不再多说乐。

(27) 如何创建和使用无模式对话框
MFC 将模式和无模式对话封装在同一个类中,但是使用无模式对话需要几个对话需要几个额处的步骤。首先,使用资源编辑器建立对话资源并使用 ClassWizard创建一个CDialog的派生类。模式和无模式对话的中止是不一样的:模式对话通过调用CDialog : : EndDialog 来中止,无模式对话则是调用CWnd: : DestroyWindow来中止的,函数CDialog : : OnOK和CDialog : : OnCancel调用EndDialog ,所以需要调用DestroyWindow并重置无模式对话的函数。
void CSampleDialog : : OnOK ( )
{
// Retrieve and validate dialog data .
if (! UpdateData (TRUE) )
{
// the UpdateData rountine
will set focus to correct item TRACEO (" UpdateData failed during dialog termination ."n")
return
}
//Call DestroyWindow instead of EndDialog .
DestroyWindow ( )
}
void CSampleDialog : : OnCancel ( )
{
//Call DestroyWindow instead of EndDialog .
DestroyWindow ( )
}
其 次,需要正确删除表示对话的C++对象。对于模式对来说,这很容易,需要创建函数返回后即可删除C++对象;无模式对话不是同步的,创建函数调用后立即返 回,因而用户不知道何时删除C++对象。撤销窗口时工作框调用CWnd : : PostNcDestroy,可以重置该函数并执行清除操作,诸如删除this指针。
void CSampleDialog : : PostNcDestroy ( )
{
// Declete the C++ object that represents this dialog.
delete this
最后,要创建无模式对话。可以调用CDialog : : DoModal创建一个模式对放,要创建一个无模式对话则要调用CDialog: : Create。下面的例子说明 了应用程序是如何创建无模式对话的: 象;无模式对话不是同步的,创建函数调用后立即返回,
void CMainFrame : : OnSampleDialog ( )
{
//Allocate a modeless dialog object .
CSampleDilog * pDialog =new CSampleDialog
ASSERT_VALID (pDialog) Destroy ( )
//Create the modeless dialog . represents this dialog.
BOOL bResult = pDialog —> Creste (IDD_IDALOG)
ASSERT (bResult )
}

(28) 如何防止主框窗口在其说明中显示活动的文档名
创建主框窗口和MDI子窗口进通常具有FWS_ADDTOTITLE风格位,如果不希望在说明中自动添加文档名, 必须禁止该风格位, 可以使用ClassWizard重置
CWnd: : PreCreateWindow并关闭FWS_ADDTOTITLE风格。
BOOL CMainFrame : : PreCreateWindow (CREATESTRUCT&cs)
{
//Turn off FWS_ADDTOTITLE in main frame .
cs.styel & = ~FWS_ADDTOTITLE  
return CMDIFrameWnd : : PreCreateWindow (cs )
}
关闭MDI子窗口的FWS _ADDTOTITLE风格将创建一个具有空标题的窗口,可以调用CWnd: : SetWindowText来设置标题。记住自己设置标题时要遵循接口风格指南。

(29) 如何在代码中获取工具条和状态条的指针
缺 省时, 工作框创建状态条和工具条时将它们作为主框窗口的子窗口,状态条有一个AFX_IDW_STATUS_BAR标识符,工具条有一个 AFX_IDW_TOOLBAR标识符,下例说明了如何通过一起调用CWnd: : GetDescendantWindow和AfxGetMainWnd来获取这些子窗口的指针:
//Get pointer to status bar .
CStatusBar * pStatusBar = (CStatusBar *) AfxGetMainWnd ( )
—> GetDescendantWindow(AFX_IDW_STUTUS_BAR)
//Get pointer to toolbar .
CToolBar * pToolBar = (CToolBar * ) AfxGetMainWnd ( )
—> GetDescendantWindow(AFX_IDW_TOOLBAR)


(30) 怎样加载其他的应用程序?
三个SDK函数 winexec, shellexecute,createprocess可以使用。
WinExec最简单,两个参数,前一个指定路径,后一个指定显示方式.后一个参数值得说一下,比如泥用 SW_SHOWMAXMIZED方式去加载一个无最大化按钮的程序,就是Neterm,calc等等,就不会出现正常的窗体,但是已经被加到任务列表里了。
ShellExecute 较 WinExex灵活一点,可以指定工作目录,下面的Example就是直接打开 c:"temp"1.txt,而不用加载与 txt文件关联的应用程序,很多安装程序完成后都会打开一个窗口,来显示Readme or Faq,我猜就是这么作的啦.
ShellExecute(NULL,NULL,_T("1.txt"),NULL,_T("c:""temp"),SW_SHOWMAXMIZED)
CreateProcess最复杂,一共有十个参数,不过大部分都可以用NULL代替,它可以指定进程的安全属性,继承信息,类的优先级等等.来看个很简单的Example:
STARTUPINFO stinfo
//启动窗口的信息
PROCESSINFO procinfo //进程的信息
CreateProcess(NULL,_T("notepad.exe"),NULL,NULL.FALSE,
NORMAL_PRIORITY_
CLASS,NULL,NULL, &stinfo,&procinfo)

(31) 如何在代码中获取工具条和状态条的指针
缺 省时, 工作框创建状态条和工具条时将它们作为主框窗口的子窗口,状态条有一个AFX_IDW_STATUS_BAR标识符,工具条有一个 AFX_IDW_TOOLBAR标识符,下例说明了如何通过一起调用CWnd: : GetDescendantWindow和AfxGetMainWnd来获取这些子窗口的指针:
//Get pointer to status bar .
CStatusBar * pStatusBar = (CStatusBar *) AfxGetMainWnd ( )
—> GetDescendantWindow(AFX_IDW_STUTUS_BAR)

(32) 如何使能和禁止工具条的工具提示
如 果设置了CBRS_TOOLTIPS风格位,工具条将显示工具提示,要使能或者禁止工具提示,需要设置或者清除该风格位。下例通过调用 CControlBar : : GetBarStyle和CControlBar : : SetBarStyle建立一个完成此功能的成员函数:
void CMainFrame : : EnableToolTips ( BOOL bDisplayTips )
{
ASSERT_VALID (m_wndToolBar)
DWORD dwStyle = m _wndToolBar.GetBarStyle ( )
if (bDisplayTips) dwStyle |=CBRS_TOOLTIPS
else
dwStyle & = ~CBRS_TOOLTIPS
m_wndToolBar.SetBarStyle (dwStyle )
}
//Get pointer to toolbar .
CToolBar * pToolBar = (CToolBar * ) AfxGetMainWnd ( )
—> GetDescendantWindow(AFX_IDW_TOOLBAR)

(33) 如何设置工具条标题
工具条是一个窗口,所以可以在调用CWnd : : SetWindowText来设置标题,例子如下:
int CMainFrame : : OnCreate (LPCREATESTRUCT lpCreateStruct )
{

// Set the caption of the toolbar .
m_wndToolBar.SetWindowText (_T "Standdard")

(34) 如何使窗口始终在最前方?
BringWindowToTop(Handle)
SetWindowPos函数,指定窗口的 最顶风格,用WS_EX_TOPMOST扩展窗口的风格
Example:
void ToggleTopMost(
CWnd *pWnd)
{
ASSERT_VALID(pWnd)
pWnd ->SetWindowPos(pWnd-> GetStyle( ) &WS_EX_TOPMOST)?
&wndNoTopMOST: &wndTopMost,0,0,0,0,SSP_NOSIZE|WSP_NOMOVE)
}

(35) 如何在对话框中显示一个位图
这要归功于Win 32先进的静态控件和Microsoft的资源编辑器,在对话框中显示位图是很容易的, 只需将图形控件拖到对话中并选择适当属性即可,用户也可以显示图标、位图以及增强型元文件。

(36) 如何改变对话或窗体视窗的背景颜色
调用CWinApp : : SetDialogBkColor可以改变所有应用程序的背景颜色。第一个参数指定了背景颜色,第二个参数指定了文本颜色。下例将应用程序对话设置为蓝色背景和黄色文本。
BOOL CSampleApp : : InitInstance ( )
{

//use blue dialog with yellow text .
SetDialogBkColor (RGB (0, 0, 255 ), RGB ( 255 ,255 , 0 ) )

}
需要重画对话(或对话的子控件)时,Windows向对话发送消息WM_CTLCOLOR,通常用户可以让Windows选择绘画背景的刷子,也可重置该消息指定刷子。下例说明了创建一个红色背景对话的步骤。
首先,给对话基类增加一人成员变量
CBursh :class CMyFormView : public CFormView
{

private :
CBrush m_ brush // background brush

}
其次, 在类的构造函数中将刷子初始化为所需要的背景颜色。
CMyFormView : : CMyFormView ( )
{
// Initialize background brush .
m_brush .CreateSolidBrush (RGB ( 0, 0, 255) )
}
最后,使用ClassWizard处理WM_CTLCOLOR消息并返回一个用来绘画对话背景的刷子句柄。注意:由于当重画对话控件时也要调用该函数,所以要检测nCtlColor参量。
HBRUSH CMyFormView : : OnCtlColor (CDC* pDC , CWnd*pWnd , UINT nCtlColor
)
{
// Determine if drawing a dialog box . If we are, return +handle to
//our own background brush . Otherwise let windows handle it .
if (nCtlColor = = CTLCOLOR _ DLG )
return (HBRUSH) m_brush.GetSafeHandle ( )
return CFormView : : OnCtlColor (pDC, pWnd , nCtlColor
)
}

(37) 如何获取一个对话控件的指针
有两种方法。其一,调用CWnd: : GetDlgItem,获取一个CWnd*指针调用成员函数。下例调用GetDlgItem,将返回值传给一个CSpinButtonCtrl*以便调用CSpinButtonCtrl : : SetPos 函数:
BOOL CSampleDialog : : OnInitDialog ( )
{
CDialog : : OnInitDialog ( )
//Get pointer to spin button .
CSpinButtonCtrl * pSpin - ( CSpinButtonCtrl *) GetDlgItem(IDC_SPIN)
ASSERT _ VALID (pSpin)
//Set spin button's default position .
pSpin —> SetPos (10)
return TRUE
}
其 二, 可以使用ClassWizard将控件和成员变量联系起来。在ClassWizard中简单地选择Member Variables标签,然后选择Add Variable …按钮。如果在对话资源编辑器中,按下Ctrl键并双击控件即可转到Add Member Variable对话。

(38) 如何禁止和使能控件
控件也是窗口,所以可以调用CWnd : : EnableWindow使能和禁止控件。
//Disable button controls .
m_wndOK.EnableWindow (FALSE )
m_wndApply.EnableWindow (FALSE )

(39) 如何改变控件的字体
由于控件是也是窗口,用户可以调用CWnd: : SetFont指定新字体。该函数用一个Cfont指针,要保证在控件撤消之前不能撤消字体对象。下例将下压按钮的字体改为8点Arial字体:
//Declare font object in class declaration (.H file ).
private : Cfont m_font
// Set font in class implementation (.Cpp file ). Note m_wndButton is a
//member variable added by ClassWizard.DDX routines hook the member
//variable to a dialog button contrlo.
BOOL CSampleDialog : : OnInitDialog ( )
{

//Create an 8-point Arial font
m_font . CreateFont (MulDiv (8 , -pDC
—> GetDeviceCaps(LOGPIXELSY) ,72). 0 , 0 , 0 , FW_NORMAL , 0 , 0,0, ANSI_CHARSER, OUT_STROKE_PRECIS ,
CLIP_STROKE _PRECIS , DRAFT _QUALITY
VARIABLE_PITCH |FF_SWISS, _T("Arial") )
//Set font for push button .
m_wndButton . SetFont (&m _font )

}

(40) 如何在OLE控件中使用OLE_COLOR数据类型
诸 如COleControl : : GetFortColor和COleControl : : GetBackColor等函数返回OLE _COLOR数据类型的颜色,而GDI对象诸如笔和刷子使用的是COLORREF数据类型,调用COleControl : : TranslateColor可以很容易地将OLE_COLOR类型改为COLORREF类型。下例创建了一个当前背景颜色的刷子:
void CSampleControl : : OnDraw (CDC* pdc
const Crect& rcBounds , const Crect& rcInvalid
)
{
//Create a brush of the cuttent background color.
CBrush brushBack (TranslateColor (GetBackColor () ) )
//Paint the background using the current backgroundcolor .
pdc—> FilllRect (rcBounds , &brushBack)
//other drawign commands

}

 

 

(41) 在不使用通用文件打开对话的情况下如何显示一个文件列表
调用CWnd: : DlgDirList或者CWnd: : DlgDirListComboBox,Windows 将自动地向列表框或组合框填充可用的驱动器名或者指定目录中的文件,下例将Windows目录中的文件填充在组合框中:
BOOL CSampleDig : : OnInitDialog ( )
{
CDialog : : OnInitDialog ( )
TCHAR szPath [MAX_PATH] = {"c:""windows"}
int nReslt = DlgDirListComboBox (szPath, IDC_COMBO , IDC_CURIDIR, DDL_READWRITE |DDL_READONLY|DDL_HIDDEN| DDL_SYSTEM|DDL_ARCHIVE)
return TRUE
}

(42) 为什么旋转按钮控件看起来倒转
需要调用CSpinCtrl : : SetRange 设置旋转按钮控件的范围,旋转按钮控件的缺省上限为0,缺省下限为100,这意味着增加时旋转按控件的值由100变为0。下例将旋转按钮控件的范围设置为0到100:
BOOL CAboutDlg : : OnInitDialog ( )
{
CDialog : : OnInitDialog ( )
//set the lower and upper limit of the spin button
m_wndSpin . SetRange ( 0 ,100 )
return TRUE
}
Visual C++ 4.0 Print对话中的Copise旋转按钮控件也有同样的问题:按下Up按钮时拷贝的数目减少,而按下Down 按钮时拷贝的数目增加。

(43) 为什么旋转按钮控件不能自动地更新它下面的编辑控件
如果使用旋转按钮的autu buddy特性, 则必须保证在对话的标记顺序中buddy窗口优先于旋转按钮控件。从Layout菜单中选择Tab Order菜单项(或者按下Crtl+D)可以设置对话的标签顺序。

(44) 如何用位图显示下压按钮
Windows 95按钮有几处新的创建风格,尤其是BS_BITMAP和BS_ICON,要想具有位图按钮,创建按钮和调用CButton : : SetBitmap或CButton : : SetIcon时要指定BS_BITMAP或BS_ICON风格。
首先,设置按钮的图标属性。然后,当对话初始化时调用CButton: : SetIcon。注意:下例用图标代替位图,使用位图时要小心,因为不知道背景所有的颜色——并非每个人都使用浅灰色。
BOOL CSampleDlg : : OnInitDialog ( )
{
CDialog : : OnInitDialog ( )
//set the images for the push buttons .
BOOL CSampleDlg : : OnInitDialog ( )
{
CDialog : : OnInitDialog ( )
//set the images for the push buttons .
m_wndButton1.SetIcon (AfxGetApp ( ) —> LoadIcon (IDI _ IPTION1))
m_wndButton2.SetIcon (AfxGetApp ( ) —> LoadIcon (IDI _ IPTION2))
m_wndButton3.SetIcon (AfxGetApp ( ) —> LoadIcon (IDI _ IPTION3))
return TRUE
}

(45) 如何一个创建三态下压按钮
可以使用新的BS_PUSHBUTTON 风格位和检测框以及按钮来创建一个三态下压按钮。这很容易,只需将检测框和按钮拖拉到对话中并指定属性Push—like即可。不用任何附加程序就可以成为三态下压按钮。

(46) 如何动态创建控件
分配一个控件对象的实例并调用其Create成员函数。开发者最容易忽略两件事:忘记指定WS_VISBLE标签和在栈中分配控件对象。下例动态地创建一个下压按钮控件:
//In class declaration (.H file ).
private : CButton* m _pButton
//In class implementation (.cpp file ) .
m_pButton =new CButton
ASSERT_VALID (m_pButton)
m_pButton —>Create (_T ("Button Title ") , WS_CHILD |WS_VISIBLE |BS_PUSHBUTTON. Crect ( 0, 0, 100 , 24) , this , IDC _MYBUTTON )

(47) 如何限制编辑框中的准许字符
如 果用户在编辑控件中只允许接收数字,可以使用一个标准的编辑控件并指定新的创建标志ES_NUMBERS,它是Windows 95新增加的标志,该标志限制 编辑控件只按收数字字符。如果用户需要复杂的编辑控件,可以使用Microsoft 的屏蔽编辑控件,它是一个很有用的OLE定制控件。
如果希望不使用OLE 定制控件自己处理字符,可以派生一个CEdit类并处理WM_CHAR消息,然后从编辑控件中过滤出特定的字符。首先,使用ClassWizard建立一 个 CEdit的派生类,其次,在对话类中指定一个成员变量将编辑控件分类在OnInitdialog 中调用CWnd: : SubclassDlgItem .
//In your dialog class declaration (.H file )
private : CMyEdit m_wndEdit // Instance of your new edit control .
//In you dialog class implementation (.CPP file )
BOOL CSampleDialog : : OnInitDialog ( )
{

//Subclass the edit lontrod .
m_wndEdit .SubclassDlgItem (IDC_EDIT,this)

}
使用ClassWizard处理WM_CHAR消息,计算nChar参量并决定所执行的操作,用户可以确定是否修改、传送字符。下例说明了如何显示字母字符,如果字符是字母字符,则调用CWnd OnChar,否则不调用OnChar.
//Only display alphabetic dharacters .
void CMyEdit : : OnChar (UINT nChar , UINT nRepCnt , UITN nFlags )
{
//Determine if nChar is an alphabetic character.
if (: : IsCharAlpha ( ( TCHAR) nChar ) )
CEdit : : OnChar (nChar, nRepCnt , nFlags )
}
如 果要修改字符,则不能仅仅简单地用修改过的nChar调用CEdit: : OnChar,然后CEdit: : OnChar调用CWnd: : Default获取原来的wParam 和lParam 的值,这样是不行的。要修改一个字符,需要首先修改nChar,然后用修改过的nChar调用CWnd: : DefWindowProc。下例说明了如何将字符转变为大写:
//Make all characters uppercase
void CMyEdit : : OnChar (UINT nChar , UINT nRepCnt , UINT nFlags )
{
//Make sure character is uppercase .
if (: : IsCharAlpha ( .( TCHAR) nChar)
nChar=: : CharUpper(nChar )
//Bypass default OnChar processing and directly call
//default window proc.
DefWindProc (WM_CHAR, nChar , MAKELPARAM (nRepCnt, nFlags ))
}

(48) 如何改变控件的颜色
有 两种方法。其一,可以在父类中指定控件的颜色,或者利用MFC4.0新的消息反射在控件类中指定颜色。 当控件需要重新着色时,工作框调用父窗口(通常是对话框)的CWnd: : OnCrtlColor,可以在父窗口类中重置该函数并指定控件的新的绘画属性。例如,下述代码将对话中的所有编辑控件文本颜色改为红色:
HBRUSH CAboutDig : : OnCtlColor (CDC * pDCM , CWnd * pWnd , UINT nCtlColor)
{
HBRUSH hbr = CDialog : : OnCtlColor (pDC, pWnd , nCtlColor )
//Draw red text for all edit controls .
if (nCtlColor= = CTLCOLOR_EDIT )
pDC —> SetTextColor (RGB (255, 0 , 0 , ) )
return hbr
}
然 而,由于每个父窗口必须处理通知消息并指定每个控件的绘画属性,所以,这种方法不是完全的面向对象的方法。控件处理该消息并指定绘画属性更合情合理。消息 反射允许用户这样做。通知消息首先发送给父窗口,如果父窗口没有处理则发送给控件。创建一个定制彩色列表框控件必须遵循下述步骤。
首先,使用ClassWizard 创建一个CListBox 的派生类并为该类添加下述数据成员。
class CMyListBox publilc CListBox
{

private
COLORREF m_clrFor // foreground color
COLORREF m_clrBack //background color
Cbrush m_brush //background brush

}
其次,在类的构造函数中,初始化数据中。
CMyListBox : : CMyListBox ()
{
//Initialize data members .
m_clrFore =RGB (255 , 255 , 0) //yellow text
m_clrBack=RGB (0 , 0 , 255) // blue background
m_brush . CreateSolidBrush (m _clrBack )
}
最后,使用ClassWizard处理反射的WM_CTLCOLOR(=WM_CTLCOLOR)消息并指定新的绘画属性。
HBRUSH CMyListBox : : CtlColor (CDC* pDC, UINT nCtlColor )
{
pDC—>SetTextColor (m_clrFore)
pDC—>SetBkColor (m_clrBack)
return (HBRUSH) m_brush.GetSafeHandle ()
}
现在,控件可以自己决定如何绘画,与父窗口无关。

(49) 当向列表框中添加多个项时如何防止闪烁
调 用CWnd::SetRedraw 清除重画标志可以禁止CListBox(或者窗口)重画。当向列表框添加几个项时,用户可以清除重画标志,然后添加项,最后恢复重画标志。为确保重画列表 框的新项,调用SetRedraw (TRUE) 之后调用CWnd::Invalidate。
//Disable redrawing.
pListBox->SetRedraw (FALSE)
//Fill in the list box gere
//Enable drwing and make sure list box is redrawn.
pListBox->SetRedraw (TRUE)
pListBox->Invalidate ()

(50) 如何向编辑控件中添加文本
由于没有CEdit:: AppendText函数,用户只好自己做此项工作。调用CEdit:: SetSel移动到编辑控件末尾,然后调用CEdit:: ReplaceSel添加文本。下例是AppendText 的一种实现方法:
void CMyEdit:: AppendText (LPCSTR pText)
{
int nLen=GetWindowTextLength ()
SetFocus ()
SetSel (nLen, nLen)
ReplaceSel (pText)
}

(51) 如何访问预定义的GDI对象
可以通过调用CDC:: SlectStockObject使用Windows的几个预定义的对象,诸如刷子、笔以及字体。下例使用了Windows预定义的笔和刷子GDI对象在视窗中画一个椭圆。
//Draw ellipse using stock black pen and gray brush.
void CSampleView:: OnDraw (CDC* pDC)
{
//Determine size of view.
CRect rcView
GetClientRect (rcView)
//Use stock black pen and stock gray brush to draw ellipse.
pDC->SelectStockObject (BLACK_PEN)
pDC->SelectStockObject (GRAY_BRUSH)
//Draw the ellipse.
pDC->Ellipse (reView)
}
也可以调用新的SDK函数GetSysColorBrush获取一个系统颜色刷子,下例用背景色在视窗中画一个椭圆:
void CsampleView:: OnDraw (CDC* pDC)
{
//Determine size of view.
CRect rcView
GetClientRect (rcView)
//Use background color for tooltips brush.
CBrush * pOrgBrush=pDC->SelectObject ( CBrush ::FromHandle( ::GetSysColorBrush (COLOR_INFOBK)))
//Draw the ellipse.
pDC->Ellipse (rcView)
//Restore original brush.
pDC->SelectObject (pOrgBrush)
}

(52) 如何获取GDI对象的属性信息
可以调用GDIObject:: GetObject。这个函数将指定图表设备的消息写入到缓冲区。下例创建了几个有用的辅助函数。
//Determine if font is bold.
BOOL IsFontBold (const CFont&font)
{
LOGFONT stFont
font.GetObject (sizeof (LOGFONT), &stFont)
return (stFont.lfBold)? TRUE: FALSE
}
//Return the size of a bitmap.
CSize GetBitmapSize (const CBitmap&bitmap)
{
BITMAP stBitmap
bitmap.GetObject (sizeof (BITMAP), &stBitmap)
return CSize (stBitmap.bmWidth, stBitmap.bmHeight)
}
//Create a pen with the same color as a brush.
BOOL CreatePenFromBrush (Cpen&pen, cost Cbrush&brush)
{
LOGBRUSH stBrush
brush.Getobject (sizeof (LOGBRUSH), &stBrush)
return pen. Createpen (PS_SOLID, 0, stBrush.ibColor)
}

(53) 如何实现一个橡皮区矩形
CRectTracker是一个很有用的类,可以通过调用CRectTracker::TrackRubberBand 响应WM_LBUTTONDOWN消息来创建一个橡皮区矩形。
下例表明使用CRectTracker移动和重置视窗中的蓝色椭圆的大小是很容易的事情。
首先,在文件档中声明一个CRectTracker数据成员:
class CSampleView : Public CView
{

public :
CrectTracker m_tracker

}
其次,在文档类的构造函数中初始化CRectTracker 对象:
CSampleDoc:: CSampleDOC ()
{
//Initialize tracker position, size and style.
m_tracker.m_rect.SetRect (0, 0, 10, 10)
m_tracker.m_nStyle=CRectTracker:: resizeInside | CRectTracker ::dottedLine
}
然后,在OnDraw函数中画椭圆和踪迹矩形:
void CSampleView:: OnDraw (CDC* pDC)
{
CSampleDoc* pDoc=GetDocument ()
ASSERT_VALID (pDoc)
//Select blue brush into device context.
CBrush brush (RGB (0, 0, 255))
CBrush* pOldBrush=pDC->SelectObject (&brush)
//draw ellipse in tracking rectangle.
Crect rcEllipse
pDoc->m_tracker.GetTrueRect (rcEllipse)
pDC->Ellipse (rcEllipse)
//Draw tracking rectangle.
pDoc->m_tracker.Draw (pDC)
//Select blue brush out of device context.
pDC->Selectobject (pOldBrush)
}
最后,使用ClassWizard处理WM_LBUTTONDOWN消息,并增加下述代码。该段代码根据鼠标击键情况可以拖放、移动或者重置椭圆的大小。
void CSampleView::OnLButtonDown (UINT nFlags, CPoint point)
{
//Get pointer to document.
CSampleDoc* pDoc=GetDocument ()
ASSERT_VALID (pDoc)
//If clicked on ellipse, drag or resize it.Otherwise create a
//rubber-band rectangle nd create a new ellipse.
BOOL bResult=pDoc->m_tracker.HitTest (point)!= CRectTracker::hitNothing
//Tracker rectangle changed so update views.
if (bResult)
{
pDoc->m_tracker.Track (this,point,TRue)
pDoc->SetModifiedFlag ()
pDoc->UpdateAllViews (NULL)
}
else
pDoc->m-tracker.TrackRubberBand(this,point,TRUE)
CView:: onLButtonDown (nFlags,point)
}

(54) 如何更新翻转背景颜色的文本
调 用CDC:: SetBkmode并传送OPAQUE用当前的背景颜色填充背景,或者调用CDC::SetBkMode并传送TRANSPAARENT使背景保持不变, 这两种方法都可以设置背景模式。下例设置背景模式为TRANSPARENT,可以两次更新串,用花色带黑阴影更新文本。黑色串在红色串之后,但由于设置了 背景模式仍然可见。
void CSampleView:: OnDraw (CDC* pDC)
{
//Determint size of view.
CRect rcView
GetClientRect (rcVieew)
//Create sample string to display.
CString str (_T ("Awesome Shadow Text..."))
//Set the background mode to transparent.
pDC->SetBKMode (TRANSPARENT)
//Draw black shadow text.
rcView.OffsetRect (1, 1)
pDc->SetTextColor (RGB (0, 0, 0))
pDC->DrawText (str, str.GetLength (), rcView, DT_SINGLELINE | DT_CENTER | DT_VCENTER)
//Draw red text.
rcView.OffsetRect (-1,-1)
pDc->SetTextColor (RGB (255, 0, 0))
pDC->DrawText (str, str.GetLength (), rcView, DT_SINGLELINE | DT_CENTER | DT_VCENTER)
}

(55) 如何创建一个具有特定点大小的字体
可以指定字体逻辑单位的大小,但有时指定字体的点的大小可能会更方便一些。可以如下将字体的点转换为字体的高度:
int nHeigth=mulDiv (nPointSize, -dc.GetDeviceCaps (LOGPIXELSY), 72)
下例创建了一个8点的Apial字体:

CClientDC dc (AqfxGetMainWnd ())
m_font. CreateFont (MulDiv (8, -dc.GetDeviceCaps (LOGPIXELSY), 72), 0, 0, 0, FW_NORMAL, 0, 0, 0, ANSI_CHARSET, OUT_STROKE_PRECIS, CLIP_STROKE_PRECIS, DRAFT_QUALITY, VARIABLE_PITCH | FF-SWISS,_T("Arial"))

(56) 如何计算一个串的大小
函数CDC:: Det text Extent 根据当前选择的字体计算一个串的高度和宽度。如果使用的不是系统字体而是其他字体,则在调用GetTextExtent之前将字体选进设备上下文中是很重 要的,否则计算高度和宽度时将依据系统字体,由此得出的结果当然是不正确的。下述样板程序当改变下压按钮的标题时动态调整按钮的大小,按钮的大小由按钮的 字体和标题的大小而定。响应消息WM_SETTEXT时调用OnSetText,该消息使用ON_MESSAE宏指令定义的用户自定义消息。
LRESULT CMyButton:: OnSettext (WPARAM wParam, LPARAM lParam)
{
//Pass message to window procedure.
LRESULT bResult=CallWindowProc (*GetSuperWndProcAddr(), m_hWnd, GetCurrentMessage() ->message,wParam,lParam)
//Get title of push button.
CString strTitle
GetWindowText (strTitle)
//Select current font into device context.
CDC* pDC=GetDc ()
CFont*pFont=GetFont ()
CFont*pOldFont=pDC->SelectObject (pFont)
//Calculate size of title.
CSize size=pDC->GetTextExent (strTitle,strTitle.GetLength())
//Adjust the button's size based on its title.
//Add a 5-pixel border around the button.
SetWindowPos (NULL, 0, 0, size.cx+10, size.cy+10, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE)
//Clean up.
pDC->SelectFont (pOldFont)
ReleaseDC (pDC)
return bResult
}

(57) 如何显示旋转文本
只 要用户使用TrueType或者GDI笔或字体就可以显示旋转文本(有些硬件设备也支持旋转光栅字体)。LOGFONT结构中的ifEscapement 成员指定了文本行和x轴的角度,角度的单位是十分之一度而不是度,例如,ifEscapement为450表示字体旋转45度。为确保所有的字体沿坐标系 统的同一方向旋转,一定要设置ifEscapement成员的CLIP_LH_ANGLES位,否则,有些字体可能反向旋转。下例使用了14点Arial 字体每间隔15度画一个串。
void CSampleView:: OnDraw (CDC* pDC)
{
//Determine the size of the window.
CRect rcClient
GetClientRect (rcClient)
//Create sample string.
CString str (_T ("Wheeee...I am rotating!"))
//Draw transparent, red text.
pDC->SetBkMode (TRANSPARENT)
pDC->SetTextColor (RGB (255,0,0))
CFont font
//font object
LOGFONT stFont //font definition
//Set font attributes that will not change.
memset (&stFont, 0, sizeof (LOGFONT))
stFont.ifheight=MulDiv (14, -pDC->GetDeviceCaps(LOGPIXELSY), 72)
stFont.ifWeight=FW_NORMAL
stFont.ifClipPrecision=LCIP_LH_ANGLES
strcpy (stFont.lfFaceName, "Arial")
//Draw text at 15degree intervals.
for (int nAngle=0 nAngle<3600 nAngle+=150)
{
//Specify new angle.
stFont.lfEscapement=nAngle
//Create and select font into dc.
font.CreateFontIndirect(&stfont)
CFont* pOldFont=pDC ->SelectObject(&font)
//Draw the text.
pDC->SelectObject(pOldFont)
font.DelectObjext()
}
}

(58) 如何正确显示包含标签字符的串
调 用GDI文本绘画函数时需要展开标签字符,这可以通过调用CDC:: TabbedTextOut或者CDC:: DrawText并指定DT_EXPANDTABS标志来完成。TabbedTextOut函数允许指定标签位的数组,下例指定每20设备单位展开一个标 签:
void CSampleView:: OnDraw (CDC* pDC)
{
CTestDoc* pDoc=GetDocument ()
ASSERT_VALID (pDoC)
CString str
str.Format (_T ("Cathy"tNorman"tOliver"))
int nTabStop=20 //tabs are every 20 pixels
pDC->TabbedtextOut (10, 10, str, 1, &nTabStop, 10)
}

(59) 如何快速地格式化一个CString对象
调用CString:: Format,该函数和printf函数具有相同的参数,下例说明了如何使用Format函数:
//Get size of window.
CRect rcWindow
GetWindowRect (rcWindow)
//Format message string.
CString strMessage
strMessage.Format (_T ("Window Size (%d, %d)"),
rcWindow.Width (), rcWindow.Height ())
//Display the message.
MessageBox (strmessage)

(60) 串太长时如何在其末尾显示一个省略号
调用CDC:: DrawText并指定DT_END_ELLIPSIS标志,这样就可以用小略号取代串末尾的字符使其适合于指定的边界矩形。如果要显示路径信息,指定DT_END_ELLIPSIS标志并省略号取代串中间的字符。
void CSampleView:: OnDraw (CDC* pDC)
{
CTestDoc* pDoc=GetDocument ()
ASSERT_VALID (pDoc)
//Add ellpsis to end of string if it does not fit
pDC->Drawtext (CString ("This is a long string"), CRect (10, 10, 80, 30), DT_LEFT | DT_END_ELLIPSIS)
//Add ellpsis to middle of string if it does not fit
pDC->DrawText (AfxgetApp () ->m_pszhelpfilePath, CRect (10, 40, 200, 60), DT_LEFT | DT_PATH_ELLIPSIS)
}

(61) 为什么即使调用EnableMenuItem菜单项后,菜单项还处于禁止状态
需要将CFrameWnd:: m_bAutomenuEnable设置为FALSE,如果该数据成员为TRUE(缺省值),工作框将自动地禁止没有ON_UPDATE_COMMAND_UI或者ON_COMMAND的菜单项。
//Disable MFC from automatically disabling menu items.
m_bAuoMenuEnable=FALSE
//Now enable the menu item.
CMenu* pMenu=GetMenu ()
ASSERT_VALID (pMenu)
pMenu->EnableMenuItem (ID_MENU_ITEM,MF_BYCOMMAND | MF_ENABLED)

(62) 如何给系统菜单添加一个菜单项
给系统菜单添加一个菜单项需要进行下述三个步骤:
首先,使用Resource Symbols对话(在View菜单中选择Resource Symbols...可以显示该对话)定义菜单项ID,该ID应大于0x0F而小于0xF000;
其次,调用CWnd::GetSystemMenu获取系统菜单的指针并调用CWnd:: Appendmenu将菜单项添加到菜单中。下例给系统菜单添加两个新的
int CMainFrame:: OnCreate (LPCREATESTRUCT lpCreateStruct)
{

//Make sure system menu item is in the right range.
ASSERT (IDM_MYSYSITEM &0xFFF0)==IDM_MYSYSITEM)
ASSERT (IDM-MYSYSITEM<0xF000)
//Get pointer to system menu.
CMenu* pSysmenu=GetSystemmenu (FALSE)
ASSERT_VALID (pSysMenu)
//Add a separator and our menu item to system menu.
CString StrMenuItem (_T ("New menu item"))
pSysMenu->Appendmenu (MF_SEPARATOR)
pSysMenu->AppendMenu (MF_STRING, IDM_MYSYSITEM, strMenuitem)

}
现在,选择系统菜单项时用户应进行检测。使用ClassWizard处理WM_SYSCOMMAND消息并检测用户菜单的nID参数:
void CMainFrame:: OnSysCommand (UINT nID,LPARAM lParam)
{
//Determine if our system menu item was selected.
if ( (nID & 0xFFF0)==IDM_MYSYSITEM)
{
//TODO-process system menu item
}
else
CMDIFrameWnd ::OnSysCommand (nID, lParam)
}
最后,一个设计良好的UI应用程序应当在系统菜单项加亮时在状态条显示一个帮助信息,这可以通过增加一个包含系统菜单基ID的串表的入口来实现。

(63) 如何确定顶层菜单所占据的菜单行数
这可以通过简单的减法和除法来实现。首先,用户需要计算主框窗口的高度和客户区;其次,从主框窗口的高度中减去客户区、框边界以及标题的高度;最后,除以菜单栏的高度。下例成员函数是一个计算主框菜单所占据的行数的代码实现。
int CMainFrame:: GetMenuRows ()
{
CRect rcFrame,rcClient
GetWindowRect (rcFrame)
GetClientRect (rcClient)
return (rcFrame.Height () -rcClient.Height () - :: GetSystemMetrics(SM_CYCAPTION) - (:: getSystemMetrics(SM_CYFRAME) *2)) / :: GetSystemMetrics(SM_CYMENU)
}

(64) 在用户环境中如何确定系统显示元素的颜色
调用SDK函数GetSysColor可以获取一个特定显示元素的颜色。下例说明了如何在MFC函数CMainFrameWnd:: OnNcPaint中调用该函数设置窗口标题颜色。
void CMiniFrameWnd:: OnNcPaint ()
{

dc.SetTextColor (:: GetSysColor (m_bActive ? COLOR_CAPTIONTEXT : COLOR_INACTIVECAPTIONTEXT))

(65) 如何查询和设置系统参数
在Windows 3.1 SDK中介绍过SDK函数SystemParametersInfo,调用该函数可以查询和设置系统参数,诸如按键的重复速率设置、鼠标双击延迟时间、图标字体以及桌面覆盖位图等等。
//Create a font that is used for icon titles.
LOGFONT stFont
∶: SystemParametersInfo (SPIF_GETICONTITLELOGFONT, sizeof (LOGFONT), &stFont, SPIF_SENDWININICHANGE)
m_font.CreateFontIndirect (&stFont)
//Change the wallpaper to leaves.bmp.
∶ : SystemParametersInfo (SPI_SETDESKWALLPAPER, 0, _T (" forest.bmp"), SPIF_UPDATEINIFILE)

(66) 如何确定当前屏幕分辨率
调用SDK函数GetSystemMetrics,该函数可以检索有关windows显示信息,诸如标题大小、边界大小以及滚动条大小等等。
//Initialize CSize object with screen size.
CSize sizeScreen (GetSystemMetrics (SM_CXSCREEN),
GetSystemMetrics (SM_CYSCREEN))

(67) 如何使用一个预定义的Windows光标
调用CWinApp:: LoadStandardCursor并传送光标标识符。
BOOL CSampleDialog:: OnSetCursor (CWnd* pWnd,
UINT nHitTest, UINT
message)
{
//Display wait cursor if busy.
if (m_bBusy)
{
SetCursor (AfxGetApp () ->LoadStandardCursor (IDC_WAIT))
return TRUE
}
return CDialog:: OnSetCursor (pWnd. nHitTest,message)
}

(68) 如何检索原先的Task Manager应用程序使用的任务列表
原 先的Task Manager应用程序显示顶层窗口的列表。为了显示该列表,窗口必须可见、包含一个标题以及不能被其他窗口拥有。调用CWnd:: GetWindow可以检索顶层窗口的列表,调用IsWindowVisible、GetWindowTextLength以及GetOwner可以确定 窗口是否应该在列表中。下例将把TaskManager窗口的标题填充到列表中。
void GetTadkList (CListBox&list)
{
CString strCaption
//Caption of window.
list.ResetContent ()
//Clear list box.
//Get first Window in window list.
ASSERT_VALID (AfxGetMainWnd ())
CWnd* pWnd=AfxGetMainWnd () ->GetWindow (GW_HWNDFIRST)
//Walk window list.
while (pWnd)
{
// I window visible, has a caption, and does not have an owner?
if (pWnd ->IsWindowVisible()
&& pWnd ->GetWindowTextLength ()
&&! pWnd ->GetOwner ())
{
//Add caption o window to list box.
pWnd ->GetWindowText (strCaption)
list.AddString (strCaption)
}
//Get next window in window list.
pWnd=pWnd ->GetWindow(GW_HWNDNEXT)
}
}

(69) 如何确定Windows和Windows系统目录
有两个SDK函数可以完成该功能。GetWindowsDirectory和GetSystemDirectory,下例说明了如何使用这两个函数:
TCHAR szDir [MAX_PATH]
//Get the full path of the windows directory.
∶ : GetWindowsDirectory (szDir, MAX_PATH)
TRACE ("Windows directory %s"n", szDir)
//Get the full path of the windows system directory.
∶ : GetSystemDirectory (szDir, MAX_PATH)
TRACE ("Windows system directory %s"n", szDir)

(70) 在哪儿创建临文件
调用SDK函数GetTemPath可以确定临时文件的目录,该函数首先为临时路径检测TMP环境变量:如果没有指定TMP,检测TMP环境变量,然后返回到当前目录。下例说明了如何创建一个临时文件。

//get unique temporary file.
CString strFile
GetUniqueTempName (strFile)
TRY
{
//Create file and write data.Note that file is closed
//in the destructor of the CFile object.
CFile file (strFile,CFile ::modeCreate | Cfile:: modeWrite)
//write data
}
CATCH (CFileException, e)
{
//error opening file
}
END_CATCH

Void GetuniqueTempName (CString& strTempName)
{
//Get the temporary files directory.
TCHAR szTempPath [MAX_PATH]
DWORD dwResult=:: GetTempPath (MAX_PATH, szTempPath)
ASSERT (dwResult)
//Create a unique temporary file.
TCHAR szTempFile [MAX_PATH]
UINT nResult=GetTempFileName (szTempPath, _T ("~ex"),0,szTempfile)
ASSERT (nResult)
strTempName=szTempFile
}

(71) 我怎样才能建立一个等待光标?
调 用 BeginWaitCursor 函 数 来 启 动 等 待 光 标,调 用 EndWaitCursor 函 数 来 结 束 等 待 光 标。要 注 意,二 者 都 要 调 用 app 的 成 员 函 数,如 下 所 示:
    AfxGetApp()->BeginWaitCursor();
    // 要做的事
    AfxGetApp()->EndWaitCursor();

(72) 我在MDI框架中有个 form 视窗。它有个取消按钮,我需要当用户按取消按钮时可关闭form视窗。我应该如何关闭该文档?
调 用 OnCloseDocument 函 数。

(73) 如何访问桌面窗口
静态函数CWnd:: GetDesktopWindow 返回桌面窗口的指针。下例说明了MFC函数CFrameWnd::BeginModalStae是如何使用该函数进入内部窗口列表的。
void CFrameWnd::BeginModalState ()
{

//first count all windows that need to be disabled
UINT nCount=0
HWND hWnd= :: GetWindow (:: GetDesktopWindow(), GW_CHILD)
while (hWnd!=NULL)
{
if (:: IsWindowEnabled (hwnd)
&& CWnd::FromHandlePermanent (hWnd)!=NULL
&& AfxIsDescendant (pParent->m_hWnd, hWnd)
&& :: SendMessage (hWnd, WM_DISABLEMODAL, 0, 0)==0)
{
++nCount
}
hWnd=:: GetWindow (hWnd, GW_HWNDNEXT)
}

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页

打赏作者

inewzone

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值