标签 ‘VC’

142010

VS日文系统下使用MS FlexGrid控件。工程为非UNICODE。
传日文ANSI String,显示乱码。
改传宽字符,显示乱码。
不解,查资料。在source管理器中修改字体,仍旧显示乱码。

翻箱倒柜一顿尝试设成控件UNICODE形式。改成了另外的乱码。醒悟,你传的本来就不是UNICODE,改UNICODE有屁用!!
对比source文件,发现,这该死的FlexGrid控件单改Font属性的时候无法保存!
于是在改Font的同时改了另外的一个属性,保存,又改回来,保存。

这个世界清净了……

212010

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");
082010

第十四个参数lpszFace一定要是等宽字体,比如”Courier New”
第十三的参数fdwPitchAndFamily一定要设成FIXED_PITCH

否则如果操作系统的默认System字体不是等宽的,你就惨了~

222009

项目的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.大功告成!!

152009

这两天一直在跟这东东较劲,今天终于有了点结果。
其实思路很简单:第一步找到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 ) ;
	}
}