|
当前位置:电脑报电子版 > 1999 年 > 15 期 > 软件世界 > C++编程俱乐部 |
《 C++编程俱乐部 》 |
问题1:在消息WM_ENABLE中用“GetDlgItem(IDC_BUTTON)->EnableWindow(FALSE);”语句来Disable一个ID_BUTTON按钮时,却没有发生变化,这是为什么? 答:CWnd类中的EnableWindow函数用来Enable或Disable一个窗口类的对象,因为CButton类继承于CWnd类,所以你也可以用它来操作一个按钮。Enable一个基于窗口类的对象可以用以下代码: pWnd->EnableWindow(TRUE); Disable一个对象可用 pWnd->EnableWindow(FALSE); 其中,pWnd为一个指向窗口对象的指针(这里是指向按钮的指针),该问题关键在于VC中消息WM_ENABLE告诉窗口它正在Disable或Enable,但它并不能使一个窗口Enable或Disable。 问题2:如何才能将最近使用过的几个文件名(包含路径)显示出来? 答:你不需要建立一个CRecentFileList类,它已经由CWinApp基类完成了。你只需在 initinstance中调用LoadStdProfileSettings()函数就可以了。CRecentFileList类中有一个CWinApp保护成员变量(如m_pRecentFileList),所以你应该在你的继承类中处理它。 void CMdiApp::OnFileMruFile1() { // TODO: Add your command handler code here CString vl_name ; ASSERT( m_pRecentFileList->GetSize() > 0); vl_name = (*m_pRecentFileList)[0]; CWinApp::OnOpenRecentFile(ID_FILE_MRU_FILE1); } 问题3:在设计浮动菜单时设定为GRAYED的菜单项,如何在运行时激活它? 答:只要在适当的时候调用EnableMenuItem函数就可以了。EnableMenuItem函数带有两个参数,一个是需要改变的菜单项的ID,而第二个参数则是通知函数应采取的动作,可以用MF_ENABLE或MF_GRAYED。 void CMyView::OnRButtonDown(UINT nFlags, CPoint point) {CScrollView::OnRButtonDown(nFlags, point); CMenu *menu, *popup; menu = new CMenu(); // load menu from resource file menu->LoadMenu( IDR_POPUPMENU ); popup = menu->GetSubMenu(0); // item 0 is DUMMY UINT nEnable; nEnable = MF_BYCOMMAND|MF_GRAYED; if( your test ) {nEnable = MF_BYCOMMAND|MF_ENABLED;} popup->EnableMenuItem( ID_YOUR_ID, nEnable ); //display menu ClientToScreen(&point); popup->TrackPopupMenu(TPM_LEFTALIGN | TPM_R IGHTBUTTON,point.x, point.y, this ); delete menu;} 其中your test为判断条件,根据具体情况来改成相应的条件。 问题4:我创建了一个使用数据库的MFC应用程序,用类模板生成CDaoRecordset直接打开数据库(不通过ODBC),请问应如何打开有密码保护的数据库? 答:方法一:请试用下面的一段代码: DAODBEngine* pDBEngine = AfxDaoGetEngine(); ASSERT(pDBEngine != NULL); COleVariant varUserName (strUserName, VT_BSTRT); COleVariant varPassword (strPassword, VT_BSTRT); DAO_CHECK(pDBEngine->put_DefaultUser (V_BSTR(&varUserName)); DAO_CHECK(pDBEngine->put_DefaultPassword (V_BSTR(&varPassword)); 方法二:使用CDaoDatabase的Open方法: MyDaoDatabase->Open(″C:\MyDatabaseFile.mdb″,FALSE,FALSE,″;PWD=MyPassWord″); 注意,请别忘了“;PWD=MyPassWord”前面的“;”号。 问题5:我想让调用的函数和被调用的函数属于同一个类,结果在调用CreateThread时出现如下错误: error C2440: ′type cast′ : cannot convert from ′unsigned long (__stdcall Cdmi::*)(void *)′ to ′unsigned long (__stdcall *)(void *)′ 答:一、unsigned long (__stdcall Cdmi::*)(void *)是指向Cdmi某个成员函数的指针。 二、unsigned long (__stdcall *)(void *)仅仅是一个C形式函数的指针。 编译器无法将一转换为二是因为C++成员函数取第一个(隐藏)参数″this pointer″ 作为成员函数,但作为静态成员时则例外。可按如下方法解决: class XMyThread {public: void StartThread(void); virtual UINT ThreadFunction(void); static UINT __bogusthreadfunc(LPVOID lpparam);}; void XMyThread::StartThread() {AfxBeginThread(__bogusthreadfunc,this);} UINT XMyThread::ThreadFunction(void) {//here you do all your real work return 0;} UINT XMyThread::__bogusthreadfunc(LPVOID lpparam) {XMyThread* This = dynamic_cast(lpparam); return This->ThreadFunction();} 由于版面有限,我们没有加入停止线程的代码。如果需要,可以继承XMyThread,并重写ThreadFunction()函数,如: class XAnotherThread : public XMyThread {virtual UINT ThreadFunction(void);}; UINT XAnotherThread :: ThreadFunction(void) {//do some other work here return 0;} |
下载本期推荐软件 | 页 首 |
《电脑报》版权所有,电脑报网站编辑部设计制作发布 |