VC小技巧

http://hi.baidu.com/taojunhelp/blog/item/8c3c5d959f7776097bf4802d.html 来源于网络 更多好文http://blog.youkuaiyun.com/Anticracker/category/94347.aspx 1)当文档被修改时,如何在标题上加上标志'*'? 重载CDocument类的虚函数virtual SetModifiedFlag: void CTest2Doc::SetModifiedFlag(BOOL bModified) { CString strTitle = GetTitle(); CString strDirtyFlag = " *"; // note space before the '*' // so we don't break Save As dialog if (!IsModified() && bModified) { SetTitle(strTitle + strDirtyFlag); } else if ( IsModified() && !bModified ) { int nTitleLength = strTitle.GetLength(); int nDirtyLength = strDirtyFlag.GetLength(); SetTitle( strTitle.Left(nTitleLength - nDirtyLength) ); } UpdateFrameCounts(); CDocument::SetModifiedFlag(bModified); } (2)VC6.0对VC5.0的兼容性? 很不幸,vc6.0在调试模式对vc5.0不兼容,但发行模式没有问题.原因在微软改变了调试模式所用dll的格式,而保留了原文件名. 因此,不要在vc6.0中打开vc5.0的调试版本工程. (3)打印和打印机的问题? 我碰到这么一个问题:在打印方法中使用了MM_LOMETRIC模式,在LOGFONT结构中改变了字体的大小,但不知道173(或者对于屏幕而言是 25)是从哪来的,它是自动的.然而当我用另外一个打印机时173并不适合.我想知道的是:我如何对所有的打印来调整这个数字. 我以前也碰到过类似的问题,我让用户改变字体(大小,颜色等等).这些改变在屏幕上看起来挺好,但是打印时太小(我的同事在程序包中加入一个放大类).原因非常简单:打印机的分辨率可能是300dpi,而屏幕的分辨率则低得多.我是这么解决的:在获得屏幕字体信息后,我获取屏幕字体的毫米级大小 (使用LPtoDP,然后将模式变为MM_LOMETRIC,调用DPtoLP),接着对打印机设定了相同的模式,再调用LPtoDP.切换回原来的模式之后,我调用了DPtoLP,这样就得到了想要的字体高度和宽度. 在LOGFONT中使用这个值,并且带有其它诸如下划线,斜体等字体信息,我实现了用户的要求. (4)CRichEditCtrl滚动条的问题? 我使用了CRichEditCtrl控制来显示某个文件中的数据(将该控制设置为只读).我已经设置了ES_MULTILINE | ES_AUTOVSCROLL,但当数据内容比控制显示多的时候,滚动条并不出现,是不是因为设置了只读属性而引起了其它的问题? ES_AUTOVSCROLL | ES_AUTOHSCROLL属性只在控制是可编辑时有效.你可心使用下面的滚动条风格来使滚动条出现:WS_VSCROLL | WS_HSCROLL,但是这样一来,不管你的数据量有多大,滚动条总是会出现. (5)从数据库中读大于32k的内容? 我在从数据库中读数据时碰到了问题.当数据栏包含超过32k的内容时,我就读不出来,我试过ODBC::SQLGetData()也不行. 哪种类型的数据库?MS SQL,SYBASE... 试试设置一下大小: BOOL CGetBlobStmt::Execute(LPCTSTR stmt) { m_cbSize = 0; m_size = 0; LPBYTE lpData; lpData = (LPBYTE)GlobalLock(m_hData); m_retcode = SQLSetStmtOption(GetHandle(),SQL_MAX_LENGTH,m_dwBytesLeft); m_retcode = SQLExecDirect(GetHandle(),(UCHAR*)stmt,SQL_NTS); if (m_retcode == SQL_SUCCESS) { m_retcode = SQLFetch(GetHandle()); if (m_retcode == SQL_SUCCESS ||m_retcode == SQL_SUCCESS_WITH_INFO) { m_retcode = SQLGetData(GetHandle(),1,SQL_C_BINARY,lpData,254,&m_cbSize); while(m_retcode == SQL_SUCCESS_WITH_INFO) { lpData+= 254; m_retcode = SQLGetData(GetHandle(),1,SQL_C_BINARY,lpData,254,&m_cbSize); } GetError(); } } GlobalUnlock(m_hData); #if TESTDATA TRACE("%ld",m_size); #endif SaveFile(); return RETVALUE; } (6)如何获得CRichEditCtrl中字符的位置? 我想在CRichEditCtrl中使用右键菜单,因此想判定光标处字符的位置,请指点. 查看如下的帮助: IRichEditOleCallback::GetContextMenu EM_SETOLECALLBACK (7)如何限制mdi子框架最大化时的大小? 用ptMaxTrackSize代替prMaxSize,如下所示: void CChildFrame::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI) { // TOD Add your message handler code here and/or call default CChildFrame::OnGetMinMaxInfo(lpMMI); lpMMI->ptMaxTrackSize.x = 300; lpMMI->ptMaxTrackSize.y = 400; } (8)如何切换视口而不破坏它们? 我创建了一个带有静态分隔区的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); } (9)改变列表控制时发生闪烁现象? 我创建了一个简单的对话框,在对话框中设置了一个列表控件,这个控件占用了对话框的全部客户区.对话框是可以改变大小的,因此我要保证列表控件在对话框中维持正确的位置,在对话框的ONSize()事件中我对列表控件使用了MoveWindow(),这起到了作用,但当用户改变对话框的大小时,列表控件不停地闪烁. 要解决这个问题,在用MoveWindow之前,先用ShowWindow(SW_HIDE)隐藏列表控件,然后在MoveWindow之后用ShowWindow(SW_SHOW)来显示列表控件. (10)处理列表控件可见项的问题? 我在一个列表控件中加入了好多条目.我通过获取某个条目是否可见或最后是哪个条目来进行处理.我看了CListCtrl::GetItem()的帮助,但是没有找到如何判断一个条目是否可见的方法. 如果你只想处理可见的条目,你可以用GetTopIndex.它返回最大可见条目的索引值,然后你再用GetCountPerPage来得到在可见区域的条目数. (11)产生线程的问题? 我在使用CreateThread时碰到了问题.我想让调用的函数和被调用的函数属于同一个类,结果在我调用CreateThread时得到如下错误: error C2440: 'type cast' : cannot convert from 'unsigned long (__stdcall Cdmi::*)(void *)' to 'unsigned long (__stdcall *)(void *)' 方法一: (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; } 方法二:Cdmi::MonitorFiles()是个静态的成员函数. (12)CFile使用了缓冲区吗? 请告诉我CFile到底有没有使用缓冲区来处理文件? CFile没有使用运行库的I/O缓冲例程,从这个意义上讲CFile并没有使用缓冲.但是有可能操作系统在处理文件时使用了缓冲区,如果你完全不需要缓冲区,你可以设置FILE_FLAG_NO_BUFFERING.CFile工作在这种模式下的唯一的方法是CFile::Attach(). (13)DAO的密码? 我创建了一个使用数据库的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"); btw:不要忘了PWD=前面的;号. (14)如何知道CListBox什么时候滚动了? 每次绘制列表框都要重绘某项,通过消息WM_CTLCOLOR从父窗口获得DC颜色.因此每欠列表框的滚动你都可以用WM_CTLCOLOR来检验是否滚动. HBRUSH CParentDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) { // is the control _the_ list box we're interested in? if( nCtlColor == CTLCOLOR_LISTBOX && pWnd->GetDlgCtrlID() == IDC_LIST ) { // if the top index changed, the list box has been scrolled int iTop = ((CListBox*)pWnd)->GetTopIndex(); if( iTop != m_iTopOld ) { // keeps tracking of the top index changes m_iTopOld = iTop; // process scrolling ... } } HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor); return hbr; } 使用这种方法可以不必为了实现这个功能而去产生一个继承类. (15)视口的不活动性如何处理? 有什么方法使CListView成为类似WM_DIASBLED的风格,或者使它和背景色一致. 方法一:你所要做的是处理CListView的WM_SETFOCUS消息,然后在TreeView中调用SetFocus, 这样,ListView就永远不会获得焦点. afx_msg void CMyListView::OnSetFocus(CWnd* pOldWnd); { // assuming m_pwndTreeView points to the valid TreeView // on the left side m_pwndTreeView->SetFocus(); } 方法二:重载PreTranslateMessage,然后当消息为WM_LBUTTONDOWN或WM_RBUTTONDOWN时返回真即可. (16)如何使用COleClientItem的IDispatch接口? 我创建了一个如何使用COleClientItem对象,我想使用它的自动化方法.有什么方法来获得IDispatch的接口?我试过以 CCmdTarget为基类的的GetIDispatch函数但却出错,我用过EnableAutomation和GetIDispatch,却什么也没得到. MSDN中有一篇关于这个的文章(TN039).如下的代码也可能是你所需要的: LPDISPATCH CMyClientItem::GetIDispatch() { ASSERT_VALID(this); ASSERT(m_lpObject != NULL); LPUNKNOWN lpUnk = m_lpObject; Run(); // must be running LPOLELINK lpOleLink = NULL; if (m_lpObject->QueryInterface(IID_IOleLink, (LPVOID FAR*)&lpOleLink) == NOERROR) { ASSERT(lpOleLink != NULL); lpUnk = NULL; if (lpOleLink->GetBoundSource(&lpUnk) != NOERROR) { TRACE0("Warning: Link is not connected!/n"); lpOleLink->Release(); return NULL; } ASSERT(lpUnk != NULL); } LPDISPATCH lpDispatch = NULL; if (lpUnk->QueryInterface(IID_IDispatch, &lpDispatch) != NOERROR) { TRACE0("Warning: does not support IDispatch!/n"); return NULL; } ASSERT(lpDispatch != NULL); return lpDispatch; } (17)关于用户自定义的消息使用? 我写了一个基于MFC应用程序的对话框,在这个程序中,我创建了等待网络传输数据的线程,一旦该线程接收到数据,它就传送一个用户自定义的消息到对话框, 使对话框知道有数据过来.但是为何在CMyDialog::PreTranslateMessage(MSG* pMsg)中能捕捉到WM_MYCMD这个消息,却不能和OnMyCommand相映射? 将你所有自定义消息的基类设为WM_APP,而不是WM_USER. (18)在打开一个文档时退出? 我有一个mdi程序,在打开文件的处理过程中,我想判断该文档是不是应用程序需要处理的文档,因此,我检测文档中的某个数字是否符合要求,如何在发现不是该文档时出现一个错误提示,然后不打开该文档? 给文档设定某个标志,如果文档不是所要的就设定它.然后OnOpenDocument中检测,当发现标志被设定后返回FALSE. (19)在CListCtrl控件中多选择项的删除? 如何从在CListCtrl中删除多个选择项? 按如下方法处理:如果你的在CListCtrl是m_list,to_delete是个整数数组. i=3D0; POSITION pos=3Dm_list.GetFirstSelectedItemPosition(); if(pos) while(pos) to_delete[i++]=3Dm_list.GetNextSelectedItem(pos); 然后用删除保存在to_delete中的项目,用GetSelectedCount来得到已选项的个数. (20)工作线程的登录状态? 我使用循环删除了用AfxBeginThread创建的线程的好几个实例.每个线程打开一个iNET连接,打开一个URL并返回结果.我需要找出哪一个或者何时这些线程进入到登录状态. 按如下方法处理:(伪代码) // Start Threads for( unsigned u = 0; u < NUMBER_OF_THREADS; u++ ) { ThreadHandleArray[ u ] = AfxBeginThread( ...... )->m_hThread; } DWORD count = NUMBER_OF_THREADS DWORD dwWait; while( count ) { dwWait = ::WaitForMultipleObjects( count, ThreadHandleArray, FALSE, INFINITE ); if( dwWait >= WAIT_OBJECT_0 && dwWait < ( WAIT_OBJECT_0 + count ) ) { dwWait -= WAIT_OBJECT_0; // dwWait now has index to thread that completed do whatever you want to do with it // set array back up for next wait if( dwWait != ( count - 1 ) ) ThreadHandleArray[ dwWait ] = ThreadHandleArray[ count - 1 ]; count--; } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值