C++/VC 学习心得

类别:编程语言 点击:0 评论:0 推荐:

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来得到这个对象的类名

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...)
/********************************************************************/

本文地址:http://com.8s8s.com/it/it26097.htm