标签 ‘VC’
一 082010
RichEdit控件做得有点白痴,不能直接追加内容,想追加必须先选中最后部分。
SetSel(-1,-1) ;
然后进行替换。颜色需要在替换之前指定。因为这个时候还没有选中的区域,所以必须自己造一个cf而不能使用GetSelectionCharFormat()。
CHARFORMAT2 cf;
memset( &cf , 0 , sizeof(cf) ) ;//这个绝对不能省!
cf.cbSize = sizeof(cf) ;
cf.dwMask = CFM_COLOR ;
cf.crTextColor = RGB(128,128,128) ;//颜色值
SetSelectionCharFormat(cf);
最后就可以替换文本了
ReplaceSel("Text");
第十四个参数lpszFace一定要是等宽字体,比如”Courier New”
第十三的参数fdwPitchAndFamily一定要设成FIXED_PITCH
否则如果操作系统的默认System字体不是等宽的,你就惨了~
项目的rc文件这两天出了大问题:持续不断的增长。
而且还是以每次改动10M的数量级增长。
编译出来的文件也从开始的400k暴涨到9.5M。
于是打开rc文件查探缘由。发现两个用到MS FlexGrid 6.0的控件资源有问题,一个长达8M,另一个更是达到了恐怖的20多M。
于是搜索解决途径。在CSDN上有人说也遇到了类似问题,是采取不用这个控件的方法解决的。不甘心,也不可能采取这样的方案。于是继续换英文关键字查找。终于找到了。里面一哥们说,把成串的0删掉就可以了。
于是动手尝试。发现对于比较少的0,确实有效。但是一次删除上kw的,就怎么也不能正常加载控件。
转回头尝试CSDN上的方法,先把超长的控件从Dialog中删除,保存RC。发现RC文件骤降到几十K,果然有效。再重新添加之后,RC也只不过长了数百字节。修改成功!!
所以,对付这种情况最有效的办法就是:
1.记住出错的FlexGrid控件的主要属性。
2.删除FlexGrid控件实例。保存RC文件。
3.重新添加FlexGrid控件,恢复属性。
4.大功告成!!
这两天一直在跟这东东较劲,今天终于有了点结果。
其实思路很简单:第一步找到Message的窗口句柄,第二步关掉它。
找句柄有若干的方法,这两天重点研究的是FindWindowEx() 和 GetLastActivePopup()。各有利弊。后述。
关窗口也有若干方法。可以发送WM_CLOSE/调用CloseWindow(), 发送WM_DESTROY/DestroyWindow(),PoseMessage(hWnd, WM_COMMAND, MAKEWPARAM(IDCANCEL,BN_CLICKED) , (LPARAM)::GetDlgItem( hWnd ,IDCANCEL ) )(发送点击button事件。根据Messagebox类型改变ID),以及EndDialog()实现。
CloseWindow()最不好用。因为它实际上只是将Messageox最小化了,并没有真正销毁。
DestroyWindo()虽然销毁了Messagebox,却没有重新激活其父窗口。在多窗口的时候会造成界面的混乱。
模拟点击Button比较万能,因为可以实现不同的逻辑效果,只是有点麻烦。
EndDialog最好用,能够安全地干掉Messagebox,并且模拟返回值(第二个参数)。
下面是查找句柄的两个例程:
一、使用GetLastActivePopup()。
前提条件:需要知道父窗口。
优点:简单明了。
缺陷:当焦点不在MessageBox上时无法将其关闭。
void DestroyMsg(HWND parent)
{
if (parent)
{
HWND hWnd = GetLastActivePopup( parent ) ; //查找激活的MessageBox
if (hWnd)
{
EndDialog( hWnd, 0 ) ;
}
}
}
二、使用FindWindowEx()。
前提条件:MessageBox的标题和内容
优点:可以找到任意MessageBox。
缺点:代码长,消耗资源大。
static BOOL CALLBACK EnumCommonProc( HWND hwnd, LPARAM lParam )
{
stMsgFeature* pstMsg = (stMsgFeature*)lParam ;
char szQuestionMsg[255] = { 0 } ;
GetWindowText( hwnd , szQuestionMsg , 255 ) ;
if ( ( strcmp( pstMsg->pszContent , szQuestionMsg ) == 0 ) )
{
// found , and exit enum
pstMsg->bFound = true ;
return false ;
}
return true ;
}
bool IsMsgWnd ( HWND hWnd , char* pszContent )
{
stMsgFeature stMsg ;
stMsg.pszContent = pszContent ;
stMsg.bFound = false ;
EnumChildWindows( hWnd,
EnumCommonProc,
LPARAM(&stMsg)) ;
return stMsg.bFound ;
}
void DestroyWnd(const char* pszCaption , const char* pszContent )
{
HWND hJigCaption = FindWindowEx(
NULL , // parent
NULL , // child after
NULL , // class
pszCaption ) ; // caption
while ( hJigCaption )
{
if ( IsMsgWnd( hJigCaption , pszContent ) )
{
break ;
}
// find next window
hJigCaption = FindWindowEx(
NULL , // parent
hJigCaption , // child after
NULL , // class
pszCaption ) ; // caption
}
if (hJigCaption)
{
::EndDialog( hJigCaption , 0 ) ;
}
}
昨天和今天遇到的奇怪問題是,在偶的exe當中調用其他人編寫的dll文件,都只能創建不能銷毀.程序一調到這些MFC擴展類的析構函數時,在return的時候就會報內存錯誤.具體查看的話,發現在要銷毀的時候,自身的指針會發生變化,所以在delete這種指針甚至在堆(heap)里銷毀的時候,就找不到自身指針.這樣當然會發生內存錯誤.
經過近兩天的調試,最終找到了原因:偶滴工程設置有問題!!
在工程的project–>Setting–>General選項卡當中.第一欄Microsoft Foundation Classes裏,偶選中滴是第一項不知什么時候變成鳥Not Using MFC.而剩下的選成無論哪個,都可以調用MFC類.
最后,為了跟其他人統一,用了第三個.雖然俺不生成dll文件.
所以,以后找bug,一定要先查一下工程的設置是不是有問題.