Q
如何处理ComboBox中的回车键?避免退出程序?
A
在一般的EDIT中采用的方法是处理PretranlateMessage(),执行代码
CWnd
*pWnd
=
GetFocus();
if(pWnd
!=
NULL)
{
if(pWnd
==
GetDlgItem(IDC_EDIT1)
{
...//IDC_EDIT1具有焦点
}
}
但在ComboBox中好象不同,是ComboBox的编辑控件得到了焦点,所以判断代码:
BOOL
CDlg::PreTranslateMessage(MSG
*pMsg)
{
if(pMsg->message==WM_KEYDOWN
&&
pMsg->wParam
==
VK_RETURN)
{
CWnd
*pWnd
=
GetFocus();
if(pWnd
!=
NULL)
{
if(pWnd->GetParent()
==
GetDlgItem(IDC_COMBO1)//更改ID
{
return
TRUE;
}
}
}
return
CDialog::PreTranslateMessage(pMsg);
}
//-------------------------------------------------
Q
动态创建的组合框如何设置下拉列表框的高度?
A
m_combo.Create(WS_CHILD
|
WS_VISIBLE
|
WS_VSCROLL
CBC_SORT
|
CBC_DROPDOWNLIST
|
WS_TABSTOP,
CRect(320,10,580,280),this,114);
//CRect的最后一个参数(这里是280)就表示下拉大小
//-------------------------------------------------
Q
是否能不选择下拉列表样式而禁止用户输入值,有什么方法可以实现?
A
将下拉列表的编辑控件设置为只读的,方法如下:
CComboBox
*pcombo;
CWnd
*pWnd
=
pcombo->GetWindow(GW_CHILD);
while(pWnd)
{
char
classname[256];
::GetClassName(pWnd->m_hWnd,classname,256)
if(strcmp(classname,"edit")
==
0)
{
CEdit
*pEdit;
pEdit
=
new
CEdit();
pEdit->SubClassWindow(pWnd->m_hWnd);
pEdit->SetReadOnly();
pWnd
=
pWnd->GetNextWindow();
delete
pEdit;
}
if(pWnd)
pWnd
=
pWnd->GetNextWindow();
}
//-------------------------------------------------
Q
ComboBox的自定义弹出菜单,想在右击组合框的编辑部分的时候弹出菜单?
A
一种方法就是在CCustomCombo的OnCtlColor函数里进行,生成ComboBox中编辑框的子类,示例:
HBRUSH
CCustomCombo::OnCtlColor(CDC
*pDC,CWnd
*pWnd,UINT
nCtlColor)
{
if(nCtlColor
==
CTLCOLOR_EDIT)
{
if(m_edit.GetSafeHwnd()==NULL)
m_eidt.SubClassWindow(pWnd->GetSafeHwnd());
}
HBRUSH
hbr
=
CComboBox::OnCtlColor(pDC,pWnd,nCtlColor);
return
hbr;
}
//其中m_edit是CEdit类的实现,它在WM_RBUTTONUP上显示右键菜单
//-------------------------------------------------
Q
如何给按钮加位图
A
对动态创建的按钮:
CButton
button;
button.Create(_T("My
Button"),WS_CHILD
|
WS_VISIBLE
|
BS_BITMAP,CRect(10,10,60,50),pParentWnd,1);
button.SetBitmap(::LoadBitmap(NULL,MAKEINTRESOURCE(IBM_CHECK)));
或者修改风格:
UINT
Style
=
Button.GetButtonStyle();
Style
=
Style
|
BS_BITMAP;
Button.SetBitmap(::LoadBitmap(NULL,MAKEINTRESOURCE(IBM_CHECK)));
//-------------------------------------------------
Q
如何在CButton派生类中以及父对话框中捕获BN_CLICKED消息?
A
于WM_NOTIFY消息相反,通知消息BN_CLICKED作为WM_COMMAND消息发送。因此应用程序应该使用ON_CONTROL_REFLECT_EC而不是ON_NOTIFY_REFLECT
//-------------------------------------------------
Q
如何判断某个对象是否具有当前焦点?
A
return
(CWnd::GetFocus()
==
pWnd);
//-------------------------------------------------
Q
如何设置编辑控件的数字属性?
A
long
Style
=
GetWindowLong(m_EditCtrl.m_hWnd,GWL_STYLE);
Style
|=
ES_NUMBER;
SetWindowLong(m_EditCtrl.m_hWnd,GWL_STYLE,Style);
//-------------------------------------------------
Q
希望在LISTCTRL中显示文件,如何才能得到explorer使用的相同图象?
A
可以将系统的ImageList加到LISTCTRL上,然后用具有SHGFI_ICON标志的SHGetFileInfo获取适当的图标索引:
//图象列表设置
HIMAGELIST
himagelist;
SHFILEINFO
fi;
CImageList
m_smalllist;
//得到系统小图标列表的句柄
himagelist
=
(HIMAGELIST)SHGetFileInfo((LPCTSTR)_T("C:\\"),0,&fi,sizeof(SHFILEINFO),SHGFI_SYSICONINDEX
|
SHGFI_SMALLICON);
//添加到小图象列表
m_smalllist.Attach(himagelist);
//设置LISTCTRL的图象列表
m_listCtrl.SetImageList(&m_smalllist,LVSIL_SMALL);
//分离图象列表
m_smalllist.Detach();
//-------------------------------------------------
Q
如何在列表的任何一列显示图标,而不是第一列?
A
LV_ITEM
item;
...
item.mask
=
LVIF_TEXT
|
LVIF_IMAGE
|
LVIF_STATE
|
LVIF_PARAM;
item.iItem
=
...//设置行号
item.lParam
=
...//如何需要就设置lparam参数
item.iSubItem
=
...//设置列号,从0开始的
item.stateMask
=
LVIS_STATEIMAGEMASK;
item.state
=
INDEXTOSTATEIMAGEMASK(...);//参数为图标号
item.iImage
=
...//设置图标号
item.pszText
=
...//显示文本
//插入新项
m_listctrl.InsertItem(&item);
//现在设置图标
m_listctrl.SetItemText(0,4,szField);
//-------------------------------------------------
Q
给LISTBOX添加新项时如何实现自动下滚?
A
在调用AddString后,添加如下代码:
m_listbox.SetTopIndex(m_listbox.GetCount()-1);
//-------------------------------------------------
Q
listBox的文本超过框的宽度时,如何让水平滚动条正常工作?
A
用下面的代码,设置滚动条的宽度为最长的字符串宽度
void
SetHorizontalExtent(CListBox
&listbox)
{
int
index
=
listbox.GetCount();
if(index
==
LB_ERROR)
return;
int
nExtent
=
0;
if(index)
{
CDC
*pDC
=
listbox.GetDC();
CFont
*poldfont
=
pDC->SelectObject(listbox.GetFont());
CString
s;
SIZE
text;
LONG
maxtxt
=
0;
whilw(index--)
{
listbox.GetText(index,s);
text
=
pDC->GetOutputTextExtent(s);
if(text.cx
>
maxtxt)
maxtxt
=
text.cx;
}
text.cx
=
maxtxt;
pDC->LPToDP(&text);
nExtent
=
text.cx+2;
pDC->SelectObject(poldfont);
listbox.ReleaseDC(pDC);
}
listbox.SetHorizontalExtent(nExtent);
}
//-------------------------------------------------
Q
在拆分视图的时候,创建了四个视图(2行2列),右下的是CFormView,其他的都是CView,在CMainFrame的OnCreateCilent不管怎么指定CRect的大小,下方的两个视图都占了整个窗口,需要拖动!
A
一般只需要在OnCreateClient的末尾添加:
m_wndSpitter.SetRowInfo(0,200,0);//添加此行代码
//-------------------------------------------------
Q
如何指定拆分窗口的最小宽度?
A
使用CSpitterWnd::SetColumnInfo()
void
SetColumnInfo(int
col,
//指定列
int
deal,
//理想宽度(像素)
int
cxmin);
//最小宽度(像素)
在使用SetColumnInfo之后还应该调用RecalLayout();重新调整布局。
//--------------------------------------------------
Q
如何判断工具栏是水平还是垂直的?
A
if((m_toolbar.GetBarStyle()
&
CBRS_ALIGN_LEFT)
==
CBRS_ALIGN_LEFT
||
(m_toolbar.GetBarStyle()
&
CBRS_ALIGN_RIGHT)
==
CBRS_ALIGN_RIGHT)
AfxMessageBox("vertical");
else
AfxMessageBox("horizontal");
//--------------------------------------------------
Q
编程方式修改工具栏按钮的可见性?
A
示例代码:
DWORD
style
=
m_toolbar.GetButtonStyle(nIndex);
if(m_bHide)
m_toolbar.SetButtonStyle(nIndex,style
&
~WS_VISIBLE);
else
m_toolbar.SetButtonStyle(nIndex,style
|
WS_VISIBLE);
m_bHide
=
!m_bHide;
//--------------------------------------------------
Q
如何在状态栏添加按钮并响应?
A
创建一个从CButton派生的CMyButton类,在主框架类添加CMyButton类的成员变量,然后在OnCreate函数中创建按钮,并把它和状态栏关联起来:
m_mybtn.Create("MyButton",WS_CHILD
|
VISIBLE,CRect(0,0,60,20),&m_WndStatusBar,0);
通过处理BN_CLICKED消息,可以在CMyButton类中处理所有的点击事件
//--------------------------------------------------
Q
如何隐藏属性CPropertySheet的标题栏,使用ModifyStyle(WINDOW_CAPTION,0)没有效果
A
创建自己的CPropertySheet派生类,并覆盖OnInitDialog,转到默认的情况后,使用ModifyStyle来删除WS_CAPTION标志
//--------------------------------------------------
Q
如何让属性页有两行标签?
A
从CPropertySheet派生类,添加PreCreateWindow的处理,在调用基类之前添加代码:
cs.style
|=
TCS_MULTILINE;
//------------------------------------------------------
Q
如何在属性表的两个页之间传递数据?
A
CPropertyPage有一个成员函数QuerySiblings(WPARAM,
LPARAM)。应用程序可以使用这个函数。
QuerySiblings生成一条PSM_QUERYSIBLINGS消息,它传递给所有的兄弟,也就是属性表上的其他属性页。
一般可创建一个所有页可见的枚举,如:
enum{QUERY_MY_STRING,
QUERY_SOMETHING_ELSE,.......}
然后,在一个属性页需要其他属性页中的信息时,使用代码:
CString
myString;
if(lL
==
QuerySiblings(QUERY_MY_STRING,(LPARAM)&myString))
{
....//获取字符串
}
提供字符串的页处理PSM_QUERYSIBLINGS消息:
LRESULT
CPageThatHasString::OnQuerySiblings(WPARAM
wParam,
LPARAM
lParam)
{
if(QUERY_MY_STRING
==
wParam)
{
*((CString
*)lParam)
=
_T(“Test
String“);
return
1L;
}
else
return
0L;
}
//----------------------------------------------------------
Q
如何让属性页具有两行标签?
A
从CPropertySheet派生一个自己的类,添加一个PreCreateWindow的处理,然后在调用基类的处理前加如下代码:cs.style
|=
TCS_MULTILINE;
//-----------------------------------------------------------
Q
如何隐藏属性页的标题栏?
A
从CPropertySheet派生一个自己的类,并覆盖OnInitDialog,在转到默认的情况以后,使用
ModifyStyle来删除标题栏标志WS_CAPTION。
ModifyStyle(WS_CAPTION,0);
//-------------------------------------------------------------------
Q
如何枚举桌面项目?
A
1
得到指向IShellFolder接口的指针
2
得到指向IMalloc接口的指针
3
得到指向IEnumIDList接口的指针
4
提取枚举中下一项目的PIDL
5
测定PIDL代表的标志符的类型
6
处理该项目
7
释放PIDL分配的内存
8
重复4到7步,知道所有的项目都枚举完
9
释放IShellFolder
IMalloc
IEnumIDList接口的指针
LPSHELLFOLDER
lpshellfolder;
LPMALLOC
lpmalloc;
LPENUMIDLIST
lpidlist;
m_namecount
=
0;
HRESULT
hr
=
SHGetDestopFolder(&lpshellfolder);
if(hr
==
NOERROR)
{
hr
=
::SHGetMalloc(&lpmalloc);
if(hr
==
NOERROR)
{
hr
=
lpshellfolder->EnumObject(NULL,SHCONTF_FOLDERS
|
SHCONTF_NONFOLDERS,&lpidlist);
if(hr
==
NOERROR)
ProcessFolder(lpshellfolder,lpmalloc,lpidlist);//custom
deal
function
lpmalloc->Release();
lpidlist->Release();
InValidate();
}
lpshellfolder->Release();
}
void
***::ProcessFolder(LPSHELLFOLDER
lpshellfolder,LPMALLOC
lpmalloc,LPENUMIDLIST
lpidlist)
{
STRRET
strret;
ULONG
numfetch;
LPITEMIDLIST
lpitemlist;
HRESULT
hr
=
lpidlist->Next(1,&lpitemlist,&numfetch);
while(hr
==
NOERROR)
{
ULONG
attributes
=
SFGAO_FOLDER;
lpshellfolder->GetAttributes(1,(const
struct
_ITEMIDLIST
**)&lpitemlist,&attributes);
if(attributes
&
SFGAO_FOLDER)
{
hr
=
lpshellfolder->GetDiaplayNameOf(lpitemlist,SHGDN_NORMAL,&strret);
if(m_nameCount
<
20)
m_names[m_namecount++]
=
strret.str;
}
lpmalloc->Free(lpitemlist);
hr
=
lpidlist->Next(1,&lpitemlist,&numfetch);
}
}
//-------------------------------------------------------------------
Q
如何创建桌面快捷方式?
A:
1
initialize
com
2
create
LShellLink
Object
3
Use
IShellLink
interface
to
get
the
pointer
about
IPersistFile
4
Use
IShellLink
interface
to
initialize
link
5
Use
LPersistFile
interface
to
save
the
link
6
Release
all
the
com
pointer
7
Com
return
to
previous
status
1
HRESULT
hr
=
CoInitialize(NULL);
if(hr
==
S_OK)
{
...//Continue
}
2
IShellLink
*pshelllink;
pshelllink
=
CoCreateInstance(CLSID_ShellLink,NULL,CLSCTX_INPROC_SERVER,IID_IShellLink,(void
**)&pshelllink);
3
IPersistFile
*persistfile;
persistfile
=
pshelllink->QueryInterface(IID_IPersistFile,(void
**)&persistfile);
4
pshelllink->SetPath("C:\\config.sys");
pshelllink->SetDescription("ShortCut
to
config.sys");
5
char
path[MAX_PATH];
GetWindowsDirectory(path,MAX_PATH);
int
len
=
strlen(path);
strcpy(&path[len],"\\desktop\\config.lik");
//change
the
char
from
ANSI
to
UNICODE
OLECHAR
widepath[MAX_PATH];
MultiByteToWideChar(CP_ACP,0,path,-1,widepath,MAX_PATH);
persistfile->Save(widepath,TRUE);
6
pshelllink->Release();
psersistfile->Release();
7
CoUnInitialize();
转自:http://blog.sina.com.cn/s/blog_5d8cc10100e42b.html