编程语言

img mac_forward

C++/VC 学习心得

发表于2004/10/29 22:01:00  2213人阅读

VC 心得:

1:  什么时候该进行物理坐标和逻辑坐标之间的转换(LPtoDP and DPtoLP)
    见VC内幕 p55
    只要不该变映射模式(MM_TEXT MM_LOENGLISH等)就用不着这种转换。

2: 按惯例,我们在直接调用win32函数时应该使用C++作用域分辨符(::)

3: OnPrepareDC 。OnDraw会自动调用它,但是其他消息控制函数,如果使用
    了视图的设备环境,就必须要人工调用它。

4:  在运行时加入对话框控件:先调用构造函数,然后再调用Create
    在调用了控件的Create函数后,还要调用其ShowWindow函数此控件
    才能在窗口上显示!!!

5:  滑杆条控件和微调按钮控件的编程 vc内幕117~119
    114面,注意在微调控件的style对话框选项卡里选择auto buddy和
    set buddy integer

6:  关于设置映射模式的问题:可以在onPrepareDC函数里面通过
 pDC->SetMapMode(****);
 通过对CEx05c例子的分析,可知,如果视图的基类是CScrollView
 那么成员函数SetScrollSizes(mapmode,***,***,***);也有同样的作用。
 通过对ex10b的分析,如果自己加了一个CDC的成员变量,那么如果view
 自身的设备环境设定了映射模式,用户自加的CDC成员变量也要设定映射
 模式,见void CEx10bView::OnInitialUpdate()
 前面有SetScrollSize 后来,用户自己的m_pdcMemory->SetMapMode();
 如果用户的mapmode和view的mapmode不同的话,用户的会否覆盖view的?
 
7: 如何加入自定义的消息,以及如何使用PostMessage.  ex07a给出了答案。
 p129(下面,定义自己的消息) 130 131 133

8: 进行图像拖动时如何防止图像不闪烁?ex10b给出了答案。
 简单点说就是要使用内存设备环境代替view本来的设备环境作为从OnPaint
 传到OnDraw的参数

9: 用BeginWaitCursor和EndWaitCursor标识鼠标状态忙。p201

10:     进度条是如何实现的?且看多线程编程的一个例子,实际上只用到timer
 ex11a p210

11: 辅助线程如何和主线程通话? ex11b, 生成全局的线程处理函数和自定义的消息处理函数用于退出。

12: 使用CEvent类来同步进程。ex11c。注意在stdAfx.h中加入#include <afxmt.h>以使用CEvent.

13: 阻塞区

14: 如何做选项卡式的属性页。p240 改进的ex12a程序。

15:  属性页的apply按钮的消息传递模式,根据ex12a。CPage1只要重载CPropertyPage::OnApply,而无需用
 classwizard去生成什么响应WM_OnApply消息的函数(其实也没有这个消息)。而对于OK按钮,即“确定”
 按钮,则根本无需自己编程,MFC已做好一切。按确定和按Apply都会导致调用OnApply(),不同的是确定
 钮同时导致关闭对话框! Apply按钮是否可用,取决于是否SetModified(true),
 在本例中,在OnCommand中调用了SetModified(true)

16: 一个比较重要的心得:关于控件和变量之间的值交换,对于那些用classwizard联系起来的变量和
 控件,DDX会做一切,不要操心,只需调用updatedata(BOOL),注意参数的含义。true是控件向变量
 传,false是变量向控件传。对于15中提到的属性页,则根本不用调用updatedata,只要按了apply
 或者“确定”,DDX就自动调用了。


17:    CWnd指针和控件ID的相互转换。GetDlgItem GetDlgCtrlID。p109

18:    如果要用SetDlgItemText()设定静态文本控件的caption,那么此静态文本控件的ID不能是

19: 多个命令映射同一个命令处理函数时的解决办法 p256 ON_COMMAND_EX
 默认值IDC_STATIC.

20: 如何处理状态栏,看EX13B,注意267面的indicators数组,除了ID_SEPARATOR以外,其他三项,
 名称末尾的字符串就是在状态栏上相应位置显示的字符。

21: 保存窗口的大小和位置,用到CPersistentFrame类,EX14A

22: 如何将工具栏上的按钮和菜单项相关联?(即菜单和菜单项具有相同的功能)。只要将此按钮的ID值
 设为和菜单项的ID值设为相同。

23: 关于已关联的工具栏按钮和菜单项的提示写法:例如Draw a circle Circle ," "之前的是菜单项的
 提示,之后的是工具栏按钮的提示。

24: 如何改变主窗口的caption,在CXXApp中的InitInstance()中加入m_pMainWnd->SetWindowText("自己的标题");

25: DECLARE_DYNAMIC(类名)  IMPLEMENT_DYNAMIC()
 保证在诊断信息转储过程中能得到类名。

26: 可序列化的类必须直接或间接地从CObject派生而来,并且在类声明中必须包含DECLARE_SERIAL  IMPLEMENT_SERIAL

27: AppWizard所生成的任何一个文档类都包含DECLARE_DYNCREATE IMPLEMENT....

28: 第十四章,在InitInstance函数中调用SetRegistryKey,使用注册表存数据。

29: 使用注册表将文件和程序关联。P355上面

30: 多文档程序启动时默认打开一个新文档的问题。
 AppWizard会自动在InitInstance中加入
  if (!ProcessShellCommand(cmdInfo))//会调用OnFileNew
  return FALSE;
 如果不想在启动时就打开一个新文档,则在此代码前面加上
  if (cmdInfo.m_nShellCommand == CCommandLineInfo::FileNew) {
  cmdInfo.m_nShellCommand = CCommandLineInfo::FileNothing;
  }

31: CListCtrl的用法 http://www.codeproject.com/listctrl/listctrldemo.asp?target=clistctrl
 注意,LVITEM 的iItem和iSubitem。前一个代表行,后一个代表行中的列。
 如何得到当前被选中的行,使用成员函数GetFirstSelectedItemPosition。

32: 如何让窗口变灰,在当前对话框调用此函数
 GetDlgItem(IDC_BUTTON_START_PROC)->EnableWindow(false);
 参数是控件ID。
 在有CView的mfc中,做法不同参见深入浅出 ex17a。
 void CStudentView::OnUpdateCommandDel(CCmdUI* pCmdUI)
 {
 // called during idle processing and when Student menu drops down
 pCmdUI->Enable(m_position != NULL);
 }

33: 如何不用AfxMessageBox("you info")而弹出对话框。用windows api的MessageBox
 lpText=TEXT("错误:无法查询有关的注册表信息");
 lpCaption=TEXT("port info");
 MessageBox(NULL,lpText,lpCaption,MB_OK);

34: 如何把整型转换成字符型
  char buffer[2];
  itoa(urint,buffer,10);

35: CListCtrl,如何在选中时使整行都变蓝(既选中状态)
 pmyListCtrl->SetExtendedStyle
    (pmyListCtrl->GetExtendedStyle()|LVS_EX_FULLROWSELECT);

36: 关于属性页,AddPage一定要放在第二个构造函数里面。
 CProSht_DcmConfig::CProSht_DcmConfig(UINT nIDCaption, CWnd* pParentWnd, UINT iSelectPage)
 :CPropertySheet(nIDCaption, pParentWnd, iSelectPage)
 {
  //AddPage(&m_CProPgDimSev);//如果放在这个构造函数里面,DoModal的时候
  //AddPage(&m_CProPgDrctrs);//将没任何反应。
 }

 CProSht_DcmConfig::CProSht_DcmConfig(LPCTSTR pszCaption, CWnd* pParentWnd, UINT iSelectPage)
 :CPropertySheet(pszCaption, pParentWnd, iSelectPage)
 {
  AddPage(&m_CProPgDimSev);
  AddPage(&m_CProPgDrctrs);
 }
 而且要在包含此CProperSheet的类的构造函数后面初始化一下这个成员,(用冒号的)
  like this:CProShtDcmCfg("");(假设CProShtDcmCfg是个CProperSheet数据成员)

37: 关于属性页的“Apply”问题。如果对于每个页当Apply时要有不同的操作,那么就重载每个页的OnApply
 函数,即使没有设定SetModified(true)(即不将Apply按钮设为可用),当按下OK按钮时,每个页面的
 OnApply()函数还是会被一一调用。(注意重载的OnApply还是要调用基类OnApply,VC会自动生成这个代码,别删)


38: 如何关掉警告信息
  下面这样加在stdafx.h中

  #pragma warning(disable : 4507 4244),后面的数字为警告码,要关哪种警告,就把警告码加进去。

39: 有关目录操作的函数 makepath,access,CreateDirectory(Ex), MakeSureDirectoryPathExists

40: 关于CRecordset类,如果我的类(继承自CRecordset)只映射一个表,那么查询,修改,插入,删除都可以
 但是如果映射了多个表,那么只能查询。

41:  AfxBeginThread无法和类成员函数使用,http://www.china-askpro.com/msg42/qa64.shtml

      解决方法:使用静态成员函数作为 AfxBeginThread 的第一个参数,可以将this指针作为第二个参数,也就是该静态成员函数的参数,然后在该静态成员函数内部使用this指针间接的来使用成员变量和函数。

MyClass{ static UINT threadProc(LPVOID pParam);}  //在头文件中

MyClass::threadProc(LPVOID pParam)//在cpp文件中

{

     ((MyClass*)pParam)->.....

}

AfxBeginThread(threadProc,(LPVOID)this); //在使用AfxBeginThread时

 

42: 关于如何做控件的文章 http://www.csdn.net/develop/Read_Article.asp?Id=18059
 值得注意的是,如何在控件中对调用对象发出消息,一个 fire****, 有趣。

43: 用ATL实现VC插件

 http://www.yesky.com/SoftChannel/72342371928702976/20030813/1721237.shtml

44: 如何得到一个对象的runtime class, 任何一个从CObject继承来的类的对象A,都可以通过A.GetRuntimeClass()->m_lpszClassName来得到这个对象的类名


45:如何在程序中得到各种对象的指针:

全局函数AfxGetApp可以得到CWinApp应用类指针
AfxGetApp()->m_pMainWnd为框架窗口指针
在框架窗口中:CFrameWnd::GetActiveDocument得到当前活动文档指针
在框架窗口中:CFrameWnd::GetActiveView得到当前活动视指针
在视中:CView::GetDocument得到对应的文档指针
在文档中:CDocument::GetFirstViewPosition,CDocument::GetNextView用来遍历所有和文档关联的视。
在文档中:CDocument::GetDocTemplate得到文档模板指针
在多文档界面中:CMDIFrameWnd::MDIGetActive得到当前活动的MDI子窗口
一般来讲用户输入消息(如菜单选择,鼠标,键盘等)会先发往视,如果视未处理则会发往框架窗口。所以定义消息映射时定义在视中就可以了,如果一个应用同时拥有多个视而当前活动视没有对消息进行处理则消息会发往框架窗口。


C++心得:

1:构造函数的一种用法,如果只需要返回一个对象,而不需要为这个对象命名
 则可以直接用构造函数  MyClass(....); 相当于*(new MyClass(....))
 见p306
 void CEx15aView::OnUpdateEditClearAll(CCmdUI* pCmdUI)
 {
  pCmdUI->Enable(GetDocument()->m_student !=CStudent()); //直接用构造函数返回了一个对象
 }

2: 集合类,如果我们想用一个集合保存混合指针则使用CObList类,如果我们想要一个类型安全的集合,
 它只包含一种类型对象的集合,那么我们就应该看看mfc库的模板指针集合类。CTypedPrtList就是
 一个很好的例子。 p331

3:   使用rand函数获得随机数。rand函数返回的随机数在0-RAND_MAX(32767)之间。如果要实现类似0-1之间的函数,可以如下:
    double randf()
    {
     return (double)(rand()/(double)RAND_MAX);
    } 

4:   重载“=”运算符的问题
 如果两个类A的对象 a1和a2,则可直接用 a1 = a2 进行赋值,不用重载。(类A的父类或子类对象是否可以放在右边?)。如果右边不是类A的对象才要重载。


5:   类中静态成员变量的初始化。
 如在myclass类中有静态成员变量 sa(假设int型)
 则应该像全局变量一样,在任何函数体之外来初始化它,而且其形式是 int myclass::sa = 0;

/*****************路径选择窗口********************/
void 类名::OnBrowse()
{
    // TODO: Add your control notification handler code here
    //::SHBrowseForFolder();
     LPCITEMIDLIST itemId;
     BROWSEINFO bi;
     char folderName[MAX_PATH];
     char selectedDir[MAX_PATH];
     HWND pHwnd=::FindWindow(NULL,"CustomCtrl");
     bi.hwndOwner=pHwnd;
     bi.pidlRoot=NULL;
     bi.pszDisplayName=folderName;
     bi.lpszTitle="请选择所在的根目录";
     bi.ulFlags=0;
     bi.lpfn=NULL;
     bi.lParam=0;
     bi.iImage=0;
     itemId=::SHBrowseForFolder(&bi);
     if(itemId)
     {
         ::SHGetPathFromIDList(itemId,selectedDir);
  m_Path.Format("%s",selectedDir);//路径在selectedDir中
  UpdateData(FALSE);
     }
}
/********************************************************/

 

 

/**********使用其他lib时出现重定义问题的solution*********************/
一.project 设置中
1.要用release/debug方式编译 不能用CT debug(crypto++自带的)
2.genernal 页中mfc的设置你的project和cryptlib 要一致,即同时为not using mfc/或其他....
3.c/c++ 页的code generation 的use runtime library 两个project要一致
            precompiled headers 均选第一个 不使用
二.如果还不行,试试如下编译方法: compile-batch build (alphakk教的,vc我不熟,有问题找他或老妖,hoto...)
/********************************************************************/

阅读全文
0 0

相关文章推荐

img
取 消
img