VC++编程常见问题解答十一 问:如何限制mdi子框架最大化时的大小? 答:用ptMaxTrackSize代替prMaxSize,如下所示: void CChildFrame::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI) { // TODO: Add your message handler code here and/or call default CChildFrame::OnGetMinMaxInfo(lpMMI); lpMMI->ptMaxTrackSize.x = 300; lpMMI->ptMaxTrackSize.y = 400; } 问:如何切换视口而不破坏它们? 我创建了一个带有静态分隔区的sdi应用程序,左边显示工作区,右过显示左边选取 的东西.我想达到的是如果在分隔区之间进行切换,而不覆盖或破坏原来的CView对 象.答:以下代码是你所想要的: class CExSplitterWnd : public CSplitterWnd { // Construction public: CExSplitterWnd(); // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CExSplitterWnd) //}}AFX_VIRTUAL // Implementation virtual ~CExSplitterWnd(); BOOL AttachView(CWnd* pView, int row, int col); BOOL DetachView(int row, int col); // Generated message map functions //{{AFX_MSG(CExSplitterWnd) // NOTE - the ClassWizard will add and remove member functions here. //}}AFX_MSG DECLARE_MESSAGE_MAP() }; CExSplitterWnd::CExSplitterWnd() { } CExSplitterWnd::~CExSplitterWnd() { } BOOL CExSplitterWnd::AttachView(CWnd* pView, int row, int col) { //Make sure the splitter window was created if (!IsWindow(m_hWnd)) { ASSERT(0); TRACE(_T("Create the splitter window before attaching windows to panes")); return (FALSE); } //Make sure the row and col indices are within bounds if (row >= GetRowCount() || col >= GetColumnCount()) { ASSERT(0); return FALSE; } //Is the window to be attached a valid one if (pView == NULL || (!IsWindow(pView->m_hWnd))) { ASSERT(0); return FALSE; } pView->SetDlgCtrlID(IdFromRowCol(row, col)); pView->SetParent(this); pView->ShowWindow(SW_SHOW); pView->UpdateWindow(); return (TRUE); } BOOL CExSplitterWnd::DetachView(int row, int col) { //Make sure the splitter window was created if (!IsWindow(m_hWnd)) { ASSERT(0); TRACE(_T("Create the splitter window before attaching windows to panes")); return (FALSE); } //Make sure the row and col indices are //within bounds if (row >= GetRowCount() || col >= GetColumnCount()) { ASSERT(0); return FALSE; } CWnd* pWnd = GetPane(row, col); if (pWnd == NULL || (!IsWindow(pWnd->m_hWnd))) { ASSERT(0); return FALSE; } pWnd->ShowWindow(SW_HIDE); pWnd->UpdateWindow(); //Set the parent window handle to NULL so that this child window is not //destroyed when the parent (splitter) is destroyed pWnd->SetParent(NULL); return (TRUE); } 问:改变列表控制时发生闪烁现象? 我创建了一个简单的对话框,在对话框中设置了一个列表控件,这个控件占用了对 话框的全部 客户区.对话框是可以改变大小的,因此我要保证列表控件在对话框中 维持正确的位置,在对话 框的ONSize()事件中我对列表控件使用了MoveWindow(), 这起到了作用,但当用户改变对话框 的大小时,列表控件不停地闪烁. 答:要解决这个问题,在用MoveWindow之前,先用ShowWindow(SW_HIDE)隐藏列表控 件,然后在MoveWindow之后用ShowWindow(SW_SHOW)来显示列表控件. 问:处理列表控件可见项的问题? 我在一个列表控件中加入了好多条目.我通过获取某个条目是否可见或最后是哪个 条目来进行 处理.我看了CListCtrl::GetItem()的帮助,但是没有找到如何判断一 个条目是否可见的方法. 答:如果你只想处理可见的条目,你可以用GetTopIndex.它返回最大可见条目的索 引值,然后 你再用GetCountPerPage来得到在可见区域的条目数. 问:产生线程的问题? 我在使用CreateThread时碰到了问题.我想让调用的函数和被调用的函数属于同一 个类,结果 在我调用CreateThread时得到如下错误: error C2440: 'type cast' : cannot convert from 'unsigned long (__stdcall Cdmi::*)(void *)' to 'unsigned long (__stdcall *)(void *)' A1:(1)'unsigned long (__stdcall Cdmi::*)(void *)'是指向Cdmi某个成员函数的指针. (2)'unsigned long (__stdcall *)(void *)'仅仅只是一个c形式函数的指针. 编译器无法将(1)转换为(2)是因为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(); } for the sake of clairty, I did not add StopThread and I did not save the CWinThread* returned by AfxBeginThread. If you wanted a thread that does other things, simply derive from XMyThread and override ThreadFunction() example: class XAnotherThread : public XMyThread { virtual UINT ThreadFunction(void); }; UINT XAnotherThread :: ThreadFunction(void) { //do some other work here return 0; } A2:Cdmi::MonitorFiles()是个静态的成员函数.