大学毕业设计笔记

2006.4.18
今天遇到两上问题:一,如何让单文档程序的主框架一打开就是最大化。解决:CMainFrame::ActivateFrame(int nCmdShow)改变框架窗口尺寸,它的任务是以nCmdShow作为参数来调用CWnd::ShowWindow函数。nCmdShow参数决定了窗口是否被最大化或者最小化,或者同时被最大化和最小化。要使窗口最大化,只需令nCmdShow=SW_SHOWMAXIMIZED即可。

二,单击list的项的任一位置,如何让该项变为选中状态。解决:List的对像.SetExtendedStyle(LVS_EX_FULLROWSELECT)

CWnd::SetWindowPlacement作用:设置框架窗口的位置和尺寸。

 

2006.4.22
combo box中,type为DropDown时,可选择也可用户输入,type为Drop List时,只可选择不可用户输入。

 

2006.4.23
在添加一个对话框时,添加一个新的类,类名取做CTestDlg,相应的头文件和源文件取做TestDlg.h和TestDlg.cpp,可是当点击ok确认建立新类时却提示:unable to open the files(d:/vcstudy/aa/TestDlg.h,d:/vcstudy/aa/TestDlg.cpp) for class "CTestDlg". 可是在d:/vcstudy/aa下却产生了TestDlg.h和TestDlg.cpp,这时只能点击cancel取消,然而在类视图中却产生了CTestDlg类,可是在classwizard中却没有显示CTestDlg这个类。解决:这是VC++6的一个BUG,此时将.clw文件删除,然后再点classwizard重建该文件即可。

spin控件的使用,参考http://www.vckbase.net/study/article/index.html,通用控件使用详解注意一点:UDS_SETBUDDYINT 旋转按钮当前值改变时自动改变伙伴窗口标题所显示的数值,这个属性对于spin控件来说比较重要,该属性可以在属性窗口改变。

::MessageBeep(MB_ICONINFORMATION):发声函数

::WinExec(_T("explorer"), SW_SHOWNORMAL):运行指定程序。

 

2006.4.24
两个对话框之间应如何传递消息。解决:在构造对话框时可以选择传入一个窗口指针(如pMFrame),有了该指针,则可以使用pMFrame->SendMessage()传递消息了。

 

2006.4.25
CString的find函数可以找到指定字符的坐标,而mid函数可以拷贝字符串中指定部分到另一CString中。

对于list控件,当选中其为list时,将只能显示一项,没有标题,也没有左右scroll bar

对于MFC来说,数组和链表的下标由POSITION给出,要得到它们的POSITION可以用FINDIndex函数来取得。即是说,要取得数组或链表中的指定一项,需要先使用FINDIndex函数取得POSITION,再用GetAt函数取得该项。

 

2006.4.26
::SHBrowseForFolder()显示文件夹选择对话框,详细内容请见http://www.vckbase.net/code Windows窗口视图/对话框/一个可以指定初始目录的目录选择对话框程序

2006.4.27
实现分割框架,以下引自MSDN:A CSplitterWnd object is usually embedded in a parent CFrameWnd or CMDIChildWnd object. Create a CSplitterWnd object using the following steps: 1.Embed a CSplitterWnd member variable in the parent frame. 2.Override the parent frame’s CFrameWnd::OnCreateClient member function. 3.From within the overridden OnCreateClient, call the Create or CreateStatic member function of CSplitterWnd. 切分窗口是通过类CSplitterWnd来表示的。其可分为动态和静态切分窗口,一般的,动态切分使用同一个视图类,静态切分使用不同的视图类。例子:http://www.vckbase.net/code WINDOWS窗口视图/单文档界面(SDI)/VC6单文档三叉分割框架(内嵌属性页) 和 http://www.vckbase.net/code WINDOWS窗口视图/单文档界面(SDI)/MSDN分割窗口例子


2006.4.28
获取屏幕尺寸等信息(GetSystemMetrics):获得特定的窗口(GetWindow、GetTopWindow、GetNextWindow、GetDesktopWindow)获取窗口大小(GetWindowRect、GetClientRect)调整窗口大小(AdjustWindowRect、AdjustWindowRectEx)
Ctrl+D:tap stop顺序设置。

 

2006.5.3
CString与char*的相互转换:
CString strValue(“Hello”);
char *szValue;
szValue=strValue.GetBuffer(szValue);
也可用(LPSTR)(LPCTSTR)对CString//  进行强制转换. 
szValue=(LPSTR)(LPCTSTR)strValue;
反过来可直接赋值:
char *szChar=NULL;
CString strValue;
szChar=new char[10];
memset(szChar,0,10);
strcpy(szChar,”Hello”);
strValue=szChar;

 

2006.5.4
AfxBeginThread:创建线程

ON_UPDATE_COMMAND_UI:控制菜单的允许/禁止

使用除Cview以外的View基类,必须在stdafx.h中加入#include <afxcview.h>

 

2006.5.5
临界区
临界区是保证在某一个时间只有一个线程可以访问数据的方法。使用它的过程中,需要给各个线程提供一个共享的临界区对象,无论哪个线程占有临界区对象,都可以访问受到保护的数据,这时候其它的线程需要等待,直到该线程释放临界区对象为止,临界区被释放后,另外的线程可以强占这个临界区,以便访问共享的数据。临界区对应着一个CcriticalSection对象,当线程需要访问保护数据时,调用临界区对象的Lock()成员函数;当对保护数据的操作完成之后,调用临界区对象的Unlock()成员函数释放对临界区对象的拥有权,以使另一个线程可以夺取临界区对象并访问受保护的数据。同时启动两个线程,它们对应的函数分别为WriteThread()和ReadThread(),用以对公共数组组array[]操作,下面的代码说明了如何使用临界区对象:

#include "afxmt.h"
int array[10],destarray[10];
CCriticalSection Section;
UINT WriteThread(LPVOID param)
{
 Section.Lock();
 for(int x=0;x<10;x++)
  array[x]=x;
 Section.Unlock();
}
UINT ReadThread(LPVOID param)
{
 Section.Lock();
 For(int x=0;x<10;x++)
  Destarray[x]=array[x];
  Section.Unlock();
}

互斥
互斥与临界区很相似,但是使用时相对复杂一些,它不仅可以在同一应用程序的线程间实现同步,还可以在不同的进程间实现同步,从而实现资源的安全共享。互斥与Cmutex类的对象相对应,使用互斥对象时,必须创建一个CSingleLock或CMultiLock对象,用于实际的访问控制,因为这里的例子只处理单个互斥,所以我们可以使用CSingleLock对象,该对象的Lock()函数用于占有互斥,Unlock()用于释放互斥。实现代码如下:
#include "afxmt.h"
int array[10],destarray[10];
CMutex Section;
UINT WriteThread(LPVOID param)
{
 CsingleLock singlelock;
 singlelock (&Section);
 singlelock.Lock();
 for(int x=0;x<10;x++)
  array[x]=x;
 singlelock.Unlock();
}
UINT ReadThread(LPVOID param)
{
 CsingleLock singlelock;
 singlelock (&Section);
 singlelock.Lock();
 For(int x=0;x<10;x++)
  Destarray[x]=array[x];
  singlelock.Unlock();
}

信号量
信号量的用法和互斥的用法很相似,不同的是它可以同一时刻允许多个线程访问同一个资源,创建一个信号量需要用Csemaphore类声明一个对象,一旦创建了一个信号量对象,就可以用它来对资源的访问技术。要实现计数处理,先创建一个CsingleLock或CmltiLock对象,然后用该对象的Lock()函数减少这个信号量的计数值,Unlock()反之。下面的代码分别启动三个线程,执行时同时显示二个消息框,然后10秒后第三个消息框才得以显示。
Csemaphore *semaphore;
Semaphore=new Csemaphore(2,2);
HWND hWnd=GetSafeHwnd();
AfxBeginThread(threadProc1,hWnd);
AfxBeginThread(threadProc2,hWnd);
AfxBeginThread(threadProc3,hWnd);
UINT ThreadProc1(LPVOID param)
{
 CsingleLock singelLock(semaphore);
 singleLock.Lock();
 Sleep(10000);
 ::MessageBox((HWND)param,"Thread1 had access","Thread1",MB_OK);
 return 0;
}
UINT ThreadProc2(LPVOID param)
{
 CSingleLock singelLock(semaphore);
 singleLock.Lock();
 Sleep(10000);
 ::MessageBox((HWND)param,"Thread2 had access","Thread2",MB_OK);
 return 0;
}

UINT ThreadProc3(LPVOID param)
{
 CsingleLock singelLock(semaphore);
 singleLock.Lock();
 Sleep(10000);
 ::MessageBox((HWND)param,"Thread3 had access","Thread3",MB_OK);
 return 0;
}


::SendMessage(ctr.m_hWnd, LVM_SETEXTENDEDLISTVIEWSTYLE,LVS_EX_GRIDLINES,LVS_EX_GRIDLINES);设置CListView的形式。


2006.5.6
在网络编程中要注意网络字节序与主机字节序的转换ntohl,ntohs,htonl,htons;


2006.5.7
访问应用程序的其它类:在论坛中找到的,很不错,放在下面:

获得CWinApp:
-在CMainFrame,CChildFrame,CDocument,CView中直接调用AfxGetApp()或用theApp
-在其它类中只能用AfxGetApp()

获得CMainFrame:
-在CMinApp中用AfxGetMainWnd()或者m_pMainWnd
-在CChildFrame中可用GetParentFrame()
-在其它类中用AfxGetMainWnd()

获得CChildFrame:
-在CView中用GetParentFrame()
-在CMainFrame中用MDIGetActive()或GetActiveFrame()
-在其它类中用AfxGetMainWnd()->MDIGetActive()或AfxGetMainWnd()->GetActiveFrame()

获得CDocument:
-在CView中用GetDocument()
-在CChildFrame中用GetActiveView()->GetDocument()
-在CMainFrame中用
-if SDI:GetActiveView()->GetDocument()
-if MDI:MDIGetActive()->GetActiveView()->GetDocument()
-在其它类中
-if SDI:AfxGetMainWnd()->GetActiveView()->GetDocument()
-if MDI:AfxGetMainWnd()->MDIGetActive()->GetActiveView()->GetDocument()

获得CView:
-在CDocument中 POSITION pos = GetFirstViewPosition();GetNextView(pos)
-在CChildFrame中 GetActiveView()
-在CMainFrame中
-if SDI:GetActiveView()
-if MDI:MDIGetActive()->GetActiveView()
-在其它类中
-if SDI:AfxGetMainWnd()->GetActiveView()
-if MDI:AfxGetMainWnd()->MDIGetActive()->GetActiveView()

总之,单视图:GetActiveView();  
  多视图要具体情况具体分析;

如果用的是CSplitterWnd分割1行2列窗口的话,要得到每个视图指针,代码如下:  
  CLeftView*   lview=(CLeftView*)m_wndSplitter.GetPane(0,0);  
  CRightView*   rview=(CRightView*)m_wndSplitter.GetPane(0,1);
//

不过要注意在doc中要取得view的指针C*View要注意类C*View声明的问题,
因为默认情况下,mfc在*View.h中已经包含了*Doc.h,如果在*Doc.h中包含
*View.h,就会引起嵌套包含问题,这样要在*Doc.h中加入 class C*View;
而在*Doc.cpp中加入 #include "*View.h"

//
其实完全可以在CYourApp中添加各种视或文档的指针,在那些视或文档初
始化的时候将指针传给CYourApp中的对应变量,这样以后不管在哪用上面
指针只需(CYourApp*)AfxGetApp()取其属性变量即可,明了而且清楚更是
方便我一直专门操作的说:)

//
我先抛块砖,有玉的砸过来!
在何时何地,你都可以通过以下方法精确的得到任何一个对象(Application,DocTemplate,Document,View,Frame)
1。通过AfxGetApp()得到当前的App对象;
2。通过AfxGetMainWnd()得到主窗口;
3。通过CMDIFrameWnd::GetActiveFrame得到当前活动窗口;
4。通过GetNextWindow()遍例所有的子窗口;(如果要得到你想要的子窗口,可以通过特定的成员变量来标志);
5。通过CWinApp::GetFirstDocTemplatePostion()以及CWinApp::GetNextDocTemplate()的组合应用来遍历所有的DocTemplate对象,并且用CDocTemplate::GetDocString()来判断当前得到的文档莫板对象是哪个。
6。通过CDocTemplate::GetFirstDocPosition()以及CDocTemplate的GetNextDoc()组合来遍历所有的该模板的文档对象,并用CDocument::GetDocTemplate()来得到文档模板,用CDocment::GetTitle() 或者GetPathName()来判断当前的文档是哪个。
7。通过CDocuemt的GetFirstViewPositon()以及GetNextView()来遍历视图对象,一般通过访问View的成员变量来区别各个视图;通过CView::GetDocument()来得到文档对象;
8。Frame->View: 通过GetActiveView方法;
9。Frame->Doc:通过GetActiveDocument();
10。View->Frame:GetParentFrame();
11。View->Doc:GetDocuemt()//前面已经说了。
12。Doc->View:前面说了;
13。Doc->Frame:不知道有没有很直接的方法。

如果窗口尺寸改变,或者恢复被遮盖部分,则应用程序自动调用OnDraw,如果数据被改,则必须调用Invalidate来通知Windows:以规则上对CView类适用,对于CTreeView似有问题。:OnDraw要有效,BEGIN_MESSAGE_MAP(CIPSnifferStringView, CView),这里的第二个参数必须为CView,若则无效。(实践经验不知正确与否)

 

2006.5.8
OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint):此处第一个参数一定要声明为CView*,如CListView*等继承类不行。

要改变Dialog及其中的控件的背景可以响应WM_CTLCOLOR,CEdit控件未设置readonly时,发送的WM_CTLCOLOR消息是:CTLCOLOR_EDIT,设置readonly后则变为CTLCOLOR_STATIC。

在CEdit中要换行/n是不行的,要/r/n。

在使用GetClientRect(),GetWindowRect(),MoveWindow()或SetWindowPos()这几个函数需要注意的是:一:GetClientRect()所得到的CRect,其top和left属性必为0,可以说它得到的是形状,与位置无关;GetWindowRect()得到的是相对于屏幕左上角的位置(但是这一位置不一定是最左和最上的,也就是说座标有可能为负),即是与位置有关。而MoveWindow()或SetWindowPos()设置时所用的是父窗口的客户坐标,因此,若是用GetWindowRect()取得的坐标,则需要转为该窗口父窗口的客户坐标GetParent()->ScreenToClient();若是用GetClientRect()取得坐标,则需要先将它转成屏幕坐标,再将屏幕坐标转成父窗口的客户坐标,所以这不是一个好方法。

当要显示的内容超过屏幕可显示的范围,要使其自动出现滚动条:SetScrollSizes(MM_TEXT,CSize(?,?)),设置CSize与内容实际大小一样即可。


2006.5.9
OnMousewheel消息函数:控件得到该消息时会向父窗口传递,直到遇到第一个能够处理该消息的窗口。CEdit控件在未设Multiline时,会向上传递该消息,但设置Multiline后,则不再向上传递消息。目前还不太清楚如何使设置了Multiline的CEdit控件向上传递该消息。
消息处理函数可实现如下(zDelta是120的倍数):
BOOL CMyView::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
    pt = GetScrollPosition();
    pt.y += zDelta/4;
    ScrollToPosition(pt);
    return CScrollView::OnMouseWheel(nFlags, zDelta, pt);
}

ADO的Connection连接数据库时当用于客户端 Connection 对象时,Mode 属性只能设置为 adModeUnknown。

 

2006.5.10
CString事实上是一个容器,它可以像一般的字符串一样以0结尾,也可以不以0结尾,不以0结尾时,CString就可以做为存放二进制流的容器了。不以0结尾的CString的声明方式:CString( LPCTSTR lpch, int nLength );

向数据库存一串二制流时需要用到SAFEARRAY对像,还有AppendChunk方法,具体实例可见 http://www.vckbase.net/code:数据库/ADO/用MFC+ADO把jpg图象文件放入ACCESS库中,ADO其它内容参考 ADO数据库编程入门(网上找)

窗体右上角的关闭按钮被点击时发出的消息为WM_CLOSE,响应函数OnClose();

 

2006.5.12
对整数的原子操作:
The functions InterlockedIncrement, InterlockedCompareExchange, InterlockedDecrement, InterlockedExchange, and InterlockedExchangeAdd provide a simple mechanism for synchronizing access to a variable that is shared by multiple threads. The threads of different processes can use this mechanism if the variable is in shared memory.

 

2006.5.14
要实现虚拟列表功能,则必需重载LVN_GETDISPINFO,该消息的响应是列表的每一行的每一项(即列)都会响应一个消息,因此更新列表也是以项,而不是行为单位的。具体实现可以参阅www.codeguru.com中数据库版块的 CodeGuru MFC Virtual List Control及其配套源代码VirtualListControl_src.zip

ADO中RecordSet对像的Getrows()方法返回的是一个二维数组,该二维数组需要用SAFEARRAY操作,SAFEARRAY的操作函数:SafeArrayCreate:创建SAFEARRAY,SafeArrayGetElement:获取一个SAFEARRAY对像,SAFEARRAY中还可以包含SAFEARRAY,具体用法可以参阅http://www.vckbase.net/code数据库/ADO/SAFEARRAY使用例子

2006.5.15
GetChunk用法完全与微软的示范例程来写,但是运行时还是出错,不知原因何在,难道是因为它是release版而我用的是debug版的原故,这一问题留待以后解决。

2006.5.23
struct tm 结构中,year的值应减去1900

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值