??xml version="1.0" encoding="utf-8" standalone="yes"?>
若将char*转换成CStringQ除了直接赋值外Q还可用CString::formatq行。例如:
char chArray[] = "This is a test";
char * p = "This is a test";
?
LPSTR p = "This is a test"; 或在已定义Unicode应的用程序中
TCHAR * p = _T("This is a test"); ?
LPTSTR p = _T("This is a test");
CString theString = chArray;
theString.format(_T("%s"), chArray);
theString = p;
2、CString转换成char*
若将CStringc{换成char*(LPSTR)cdQ常怋用下列三U方法:
Ҏ一Q用强制{换。例如:
CString theString( "This is a test" );
LPTSTR lpsz =(LPTSTR)(LPCTSTR)theString; Ҏ二,使用strcpy。例如:
CString theString( "This is a test" );
LPTSTR lpsz = new TCHAR[theString.GetLength()+1];
_tcscpy(lpsz, theString); 需要说明的是,strcpy(或可UdUnicode/MBCS的_tcscpy)的第二个参数? const wchar_t* (Unicode)或const char* (ANSI)Q系l编译器会自动对其q行转换?
Ҏ三,使用CString::GetBuffer。例如:
CString s(_T("This is a test "));
LPTSTR p = s.GetBuffer();
// 在这里添加用p的代?
if(p != NULL) *p = _T('\0');
s.ReleaseBuffer(); // 使用完后及时释放Q以便能使用其它的CString成员函数
]]> WORD wVersionRequested = MAKEWORD(1, 1);
2 WSADATA wsaData;
3 int err = WSAStartup(wVersionRequested, &wsaData);
4 if (err != 0)
5
{
6 WSACleanup();
7 }
]]>Edit<输入?/span>>
1.(CWnd *)GetDlgItem(IDC_EDIT_1))->SetWindowText("0");
2.int n=GetDlgItemInt(IDC_EDIT_1, NULL,true);
3.(CWnd *)GetDlgItem(IDC_EDIT_1))->GetWindowText(cs);
Combox<下拉?/span>>
1.((CComboBox *)GetDlgItem(IDC_COMB_1))->SetCurSel(1);
2. GetDlgItemText(IDC_COMB_1, cs, 50);
3.int i=m_COM.GetCurSel();
m_COM.GetLBText(i,cs);
4.m_COM.AddString(cs);m_COM.DeleteString(0);m_COM.SetCurSel(0);
Radio<单选按?/span>>
1.((CButton *)GetDlgItem(IDC_RADIO_1))->SetCheck(true);
2.if (((CButton *)GetDlgItem(IDC_RADIO_1))->GetCheck())
{}
3.((CButton *)GetDlgItem(IDC_RADIO_1))->SetCheck(true);
List Control<列表>
1.m_list2.SetExtendedStyle(LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES); m_list2.InsertColumn(0,"TagID",LVCFMT_LEFT,60);
m_list2.InsertColumn(1,"TagType",LVCFMT_CENTER,120);
m_list2.InsertItem(i,cs1);
m_list2.SetItemText(i,1,cs2);
2.if(m_list2.GetSelectedItem()!=-1)
{
int i=m_list2.GetSelectionMark();
cs=m_list2.GetItemText(i,0);
}
3.int i=m_List2.GetItemCount();
4.m_list2.DeleteItem(i);m_list2.DeleteAllItems();
ListBox<列表?/span>>
1.((CListBox *)listBox)->InsertString(0, str);
Button<按钮>
1.((CWnd *)GetDlgItem(IDC_BUTTON_1))->ShowWindow(true);
2.((CWnd *)GetDlgItem(IDC_BUTTON_1))->EnableWindow(true);
]]>
]]>
一、创建动态控Ӟ
Z对照Q我们先来看一下静态控件的创徏?br>
攄静态控件时必须先徏立一个容器,一般是对话框,q时我们在对话框~辑H口中,从工L口中拖出所需控g攑֜对话框中卛_Q再适当修改控gIDQ设|控件属性,一个静态控件就创徏好了Q当对话框被昄Ӟ其上的控件也会显C?br>
静态控件不需要调用Create()函数来创建?br>
而创建动态控件有很大不同Q以下以按钮ZQ看一下动态控件的创徏q程Q?br>
1.建立控gIDP
IDh控g的标识,创徏控g前必d为它讄一个ID受?br>
打开资源中的“String Table”Q在I白行上双击鼠标Q这时会弹出一个ID属性对话框Q在其中的ID~辑框中输入IDQ如QIDC_MYBUTTONQ在Caption中输入控件标题或注解Q注QCaption框不能ؓI,为空会导致创建失败)Q这里我输入的是按钮上要昄的文?-动态按钮?br>
2.建立控g对象Q?br>
不同U类的控件应创徏不同的类对象Q?br>
·按钮控g CButton Q包括普通按钮、单选按钮和复选按钮)
·~辑控g CEdit
·静态文本控?CStatic
·标签控g CTabCtrl
·旋{控g CSpinButtonCtrl
·滑标控g CSliderCtrl
·多信息编辑控?CRichEditCtrl
·q度条控?CProgressCtrl
·滚动条控?CSrcollBar
·l合框控?CComboBox
·列表框控?CListBox
·囑փ列表控g CImageCtrl
·树状控g CTreeCtrl
·动画控g CAnimateCtrl
本例中我们创Z个CButtoncȝ普通按钮。注意不能直接定义CButton对象Q如QCButton m_MyBut;q种定义只能用来l静态控件定义控制变量,不能用于动态控件?br>
正确做法是用new调用CButton构造函数生成一个实例:
CButton *p_MyBut = new CButton();
然后用CButtoncȝCreate()函数创徏Q该函数原型如下Q?br>
BOOL Create( LPCTSTR lpszCaption, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID );
lpszCaption是按钮上昄的文本;dwStyle指定按钮风格Q可以是按钮风格与窗口风格的l合Q取值有Q?br>
H口风格Q?br>
·WS_CHILD 子窗口,必须?br> ·WS_VISIBLE H口可见Q一般都?br> ·WS_DISABLED 用H口Q创建初始状态ؓ灰色不可用的按钮时?br> ·WS_TABSTOP 可用Tab键选择
·WS_GROUP 成组Q用于成l的单选按钮中的第一个按?br>
按钮风格Q?br>
·BS_PUSHBUTTON 下压式按钮,也即普通按?br> ·BS_AUTORADIOBUTTON 含自动选中状态的单选按?br> ·BS_RADIOBUTTON 单选按钮,不常?br> ·BS_AUTOCHECKBOX 含自动选中状态的复选按?br> ·BS_CHECKBOX 复选按钮,不常?br> ·BS_AUTO3STATE 含自动选中状态的三态复选按?br> ·BS_3STATE 三态复选按钮,不常?br>
以上风格指定了创建的按钮cdQ不能同时用,但必L其一?br>
·BS_BITMAP 按钮上将昄位图
·BS_DEFPUSHBUTTON 讄为默认按钮,只用于下压式按钮Q一个对话框中只能指定一个默认按?br> ·rect指定按钮的大和位置Q?br> ·pParentWnd指示拥有按钮的父H口Q不能ؓNULLQ?br> ·nID指定与按钮关联的IDP用上一步创建的ID受?br>
不同控gcȝCreate()函数略有不同Q可参考相兌料?br>
例:p_MyBut->Create( "动态按?, WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, CRect(20,10,80,40), this, IDC_MYBUTTON );
q样Q我们就在当前对话框中的(20,10)处创Z?0Q高30Q按钮文字ؓ“动态按?#8221;的下压式按钮?br>
Z使创E更方便易用Q我定义了如下函敎ͼ
CButton* CTextEditorView::NewMyButton(int nID,CRect rect,int nStyle)
{
CString m_Caption;
m_Caption.LoadString( nID ); //取按钮标?br>CButton *p_Button = new CButton();
ASSERT_VALID(p_Button);
p_Button->Create( m_Caption, WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | nStyle, rect, this, nID ); //创徏按钮
return p_Button;
}
其中m_Caption.LoadString( nID )是从字符串表中读取按钮文本,q样在创建按钮IDӞ应该把文本设|好Q参数nStyle为除必须风格外的额外风格?br>
以下Q我调用该函数创Z个按钮,q指定第一个按钮ؓ默认按钮Q按钮的ID已预先设|好了:
CButton *p_MyBut[3];
p_MyBut[0] = NewMyButton( ID_MYBUT1, CRect(10,20,50,35), BS_DEFPUSHBUTTON );
p_MyBut[1] = NewMyButton( ID_MYBUT2, CRect(55,20,95,35), 0 );
p_MyBut[2] = NewMyButton( ID_MYBUT3, CRect(100,20,140,35), 0 );
二、动态控件的响应Q?br>
动态控件的响应函数不能用ClassWizarddQ只能手动添加。仍以上面的按钮ZQ我们制作按钮的单击响应函数?br>
1.在MESSAGE_MAP中添加响应函敎ͼ
MESSAGE_MAP表中定义了消息响应函敎ͼ其格式ؓQ消息名(ID,函数?Q当我们用ClassWizardd函数Ӟ会自动添加在AFX_MSG_MAP括v的区间内Q如Q?br>
BEGIN_MESSAGE_MAP(CTextEditorView, CFormView)
//{{AFX_MSG_MAP(CTextEditorView)
ON_BN_CLICKED(IDC_ICONBUT0, OnIconbut0)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
手工d时不要添加到AFX_MSG_MAP区间内,以防ClassWizard不能正常工作Q如Q?
BEGIN_MESSAGE_MAP(CTextEditorView, CFormView)
//{{AFX_MSG_MAP(CTextEditorView)
ON_BN_CLICKED(IDC_ICONBUT0, OnIconbut0)
//}}AFX_MSG_MAP
ON_BN_CLICKED(ID_MYBUT1, OnMybut1)
ON_BN_CLICKED(ID_MYBUT2, OnMybut2)
ON_BN_CLICKED(ID_MYBUT3, OnMybut3)
END_MESSAGE_MAP()
其中ON_BN_CLICKED是按钮单L息?br>
2.在头文g中添加函数定义:
用ClassWizardd函数Ӟ会在头文件的AFX_MSG区间内添加函数定义,如:
protected:
//{{AFX_MSG(CTextEditorView)
afx_msg void OnIconbut0();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
我们模仿q种形式Q只是把函数定义d到AFX_MSG区间外就行了Q?br>
protected:
//{{AFX_MSG(CTextEditorView)
afx_msg void OnIconbut0();
//}}AFX_MSG
afx_msg void OnMybut1();
afx_msg void OnMybut2();
afx_msg void OnMybut3();
DECLARE_MESSAGE_MAP()
3.~写消息响应函数Q?br>
以上是把消息和函数关联v来了Q具体在单击按钮后应做的工作在函C完成Q?
void CTextEditorView::OnMybut1()
{
MessageBox( "哈!你单M动态按钮? );
}
void CTextEditorView::OnMybut2()
{
……
}
void CTextEditorView::OnMybut3()
{
……
}
除了按钮的响应函数外Q你q可以用上面获得的指针访问按钮,如:
修改按钮的大和位置Qp_MyBut[0]->MoveWindow(……);
修改按钮文本Qp_MyBut[0]->SetWindowText(……);
昄/隐藏按钮Qp_MyBut[0]->ShowWindow(……);{等?br>三、回收资源:
׃动态控件对象是由new生成的,它不会被E序自动释放Q所以需手工释放。在控g不再使用时可以删除它Q?br>
if( p_MyBut[0] )
delete p_MyBut[0];
以上是按钮控g动态生成的Ҏ。下面,再看一下单选按钮的动态生成问题?四、实例:单选按钮组的动态生?br>
单选按钮也属于CButtonc,但由于单选按钮L成组使用的,所以它在制作和使用上与普通按钮有一定区别?br>
假设有三个单选按钮组成一l,初始ӞW一个单选按钮处于选中状态?br>
我们先来看静态制作方法:在对话框中放|三个单选按钮,讄属性如下:
·Radio1属性:Visible、Group、Tab stop、Auto
·Radio2属性:Visible、Tab stop、Auto
·Radio3属性:Visible、Tab stop、Auto
q样的属性设|就把三个单选按钮分成了一l,它们一ơ只能有一个被选中Q若对话框中q有其它成组的单选按钮,使用时也会互不干扰。但q时q没有ɽW一个按钮处于选中状态?br>
接着qClassWizardl单选按钮添加变量,q里只需为第一个单选按钮添加变量即可。设变量名ؓm_RadioQ类型选ؓint型。在构造函CClassWizard把m_Radio的D|ؓ-1Q我们把它改?Q这样在q行E序时可以看到第一个单选按钮处于选中状态了。之后,q应该用ClassWizardZ个单选按钮添加单d应函敎ͼ在里面修改m_Radio的值对应三个单选按钮就可以了?br>
以上是通常制作单选按钮组的办法,现我们欲改ؓ动态生成,主要要解x钮分l和单击控制问题。以下ؓ制作步骤Q?br>
1.定义三个单选按钮的IDQ?br>
打开资源中的“String Table”Q在其中d三个ID|
·W一个:ID为IDC_MYRADIO1QCaption为单?
·W二个:ID为IDC_MYRADIO2QCaption为单?
·W三个:ID为IDC_MYRADIO3QCaption为单?
其中Caption为按钮上要显C的文字Q可Ҏ需要设|?br>
2.用CButtoncȝCreate()函数生成三个单选按钮:
为方便v见,先定义一个函数生成单选按钮:
CButton* CTextEditorView::NewMyRadio(int nID,CRect rect,int nStyle)
{
CString m_Caption;
m_Caption.LoadString( nID ); //取按钮标?br> CButton *p_Radio = new CButton();
ASSERT_VALID(p_Radio);
p_Radio->Create( m_Caption, WS_CHILD | WS_VISIBLE | nStyle | WS_TABSTOP | BS_AUTORADIOBUTTON, rect, this, nID ); //创徏按钮
return p_Radio;
}
函数LoadString()用于?#8220;String Table”中读取按钮文本,Create()函数中设定了单选按钮必ȝ属性,其中包括了Visible、Tab stop、Auto属性?br>
参数nID为单选按钮IDPrect为单选按钮尺寸,nStyle为除必要属性外的其它属性。返回gؓ指向新徏按钮的指针?br>
有了q个函数后,创徏单选按钮组时只要依ơ调用该函数卛_Q其中单选按钮组的第一个单选按钮必L定WS_GROUP属性?br>
CButton *p_MyRadio[3];
p_MyRadio[0] = NewMyRadio( IDC_MYRADIO1, CRect(15,90,60,105), WS_GROUP );
p_MyRadio[1] = NewMyRadio( IDC_MYRADIO2, CRect(15,108,60,123), 0 );
p_MyRadio[2] = NewMyRadio( IDC_MYRADIO3, CRect(15,126,60,141), 0 );
3.定义单选按钮组的控制变量,讄W一个单选按钮ؓ选中状态:
q里不能用ClassWizardd变量Q也不要在DoDataExchange()中添加控制变量,因ؓ动态控件一开始ƈ不存在,在DoDataExchange()中添加控制变量会造成q行错误。这里我们只需在头文g中随意定义一个int型变量作为控制变量即可,如:
int m_SelRadio;
在构造函C讄其初gؓ0Qm_SelRadio = 0;
在上面的创徏按钮的语句中Q用SetCheck()函数讄初始选中的按钮:
CButton *p_MyRadio[3];
p_MyRadio[0] = NewMyRadio( IDC_MYRADIO1, CRect(15,90,60,105), WS_GROUP );
p_MyRadio[1] = NewMyRadio( IDC_MYRADIO2, CRect(15,108,60,123), 0 );
p_MyRadio[2] = NewMyRadio( IDC_MYRADIO3, CRect(15,126,60,141), 0 );
p_MyRadio[m_SelRadio]->SetCheck(1); //讄W一个单选ؓ选中状?
在SetCheck()函数中,参数?表示讄为选中状态,?表示未选中状态?br>
4.d鼠标单击响应函数Q?br>
鼠标单击某单选按钮后Q其状态已l能自动改变Q这里我们还需修改控制变量m_SelRadio的|以便跟踪选中的单选按钮?br>
首先在MESSAGE_MAP中把鼠标单击消息与响应函数联pv来:
BEGIN_MESSAGE_MAP(CTextEditorView, CFormView)
//{{AFX_MSG_MAP(CTextEditorView)
ON_BN_CLICKED(IDC_ICONBUT0, OnIconbut0) //ClassWizard在此处添?br>//}}AFX_MSG_MAP
ON_BN_CLICKED(IDC_MYRADIO1, OnMyRadio1) //单选按?
ON_BN_CLICKED(IDC_MYRADIO2, OnMyRadio2) //单选按?
ON_BN_CLICKED(IDC_MYRADIO3, OnMyRadio3) //单选按?
END_MESSAGE_MAP()
然后在头文g的MESSAGE_MAP中定义单d敎ͼ
protected:
//{{AFX_MSG(CTextEditorView)
afx_msg void OnIconbut0(); //ClassWizard在此处添?br>//}}AFX_MSG
afx_msg void OnMyRadio1(); //单选按?
afx_msg void OnMyRadio2(); //单选按?
afx_msg void OnMyRadio3(); //单选按?
DECLARE_MESSAGE_MAP()
q里注意不要把函数加在AFX_MSG区间内,以防影响ClassWizard的用?br>
定义具体的响应函敎ͼq里是用手工加入的,不是用ClassWizard加入的)Q?br>
//单击单选按? void CTextEditorView::OnMyRadio1()
{
m_SelRadio=0;
}
//单击单选按? void CTextEditorView::OnMyRadio2()
{
m_SelRadio=1;
}
//单击单选按? void CTextEditorView::OnMyRadio3()
{
m_SelRadio=2;
}
5.回收资源Q?br>
在析构函CQ回收创建的单选按钮(也可以在不用单选按钮时立即回收Q:
CTextEditorView::~CTextEditorView()
{
int i;
for( i=0; i<3; i++)
{
if(p_MyRadio[i])
delete p_MyRadio[i];
}
}
以上是动态控件的生成和响应方法,各种不同的控件做法略有不同,但思\和步骤都是类似的Q希望以上实例对你能够有所帮助?
]]>
{
......
public:
typedef ITaskbarList *LPITaskbarList;
LPITaskbarList pTaskbar;
......
};
Step 2: 初始?d栏COM 对象
BOOL CXDlg::OnInitDialog()
{
......
// Initializes the Component Object Model(COM)
CoInitialize(0);
// We call below function since we only need to create one object
CoCreateInstance(
CLSID_TaskbarList,
0,
CLSCTX_INPROC_SERVER,
IID_ITaskbarList,
(void**)&pTaskbar
);
// Below function will initialize the taskbar list object
pTaskbar->HrInit();
......
}
Step 3: 使用Q删?昄 d栏程序按?/u>
void CXDlg::OnBnClickedButtonHide()
{
pTaskbar->DeleteTab(this->GetSafeHwnd());
}
void CXDlg::OnBnClickedButtonShow()
{
pTaskbar->AddTab(this->GetSafeHwnd());
}
GardenUI(免费Q界面效果挺好的,XMLQ代?界面 分离)
http://www.gardenui.com/
CJLib(开源,免费QUNICODE~码,是xtreme toolkit的前生,但xtreme toolkit收费?
http://www.codejock.com/
LibUIDK(部分免费Q不开源,效果?适合贴图)
http://www.iuishop.com/download.htm
BCGControlBar(收费Q界面感觉和OfficecM)
http://www.bcgsoft.com
SKin++(收费Q界面很好看Q从它的截图上可以看?
http://www.uipower.com/
SkinMagic(收费Q看h像Office)
http://appspeed.com/html/download.html
ActiveSkin(未知)
http://www.softshape.com/software/develop/
SYGUI(收费,cMOffice)
http://www.sygui.com/
_declspec(dllexport)int subtract(int a, int b)
{
return a-b;
}
_declspec(dllexport)表示为导出函?可供应用E序调用?extern C"表示,可以使用其他~程语言讉Kdll中的函数.
~译后可以得到DLL1.DLL文g.
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
dlltest.dlg
extern int add(int x,int y);
extern int subtract(int x,int y);
//_declspec(dllimport) int add(int a, int b )
//_declspec(dllimport)int subtract(int a, int b) //q样的方法告诉编译器q些函数是从一个dll中调用的函数.~译器就能调用相应的lib文g,提高q行效率
extern可以|于变量或?/font>函数前,以标C变量或?/font>函数的定义在别的文g中,提示~译器遇到此变量?/font>函数时在其他模块中寻扑օ定义
CString str;
str.Format("3+5=%d",add(3,5));
MessageBox(str);
~译器工E属性LINK-->input-->additional dependencies d相应的lib文g,LINK-->input-->Module defintion fileddef文g.
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
如何昑ּ的加载一个动态链接库
动态加载不需要lib文g,只需要dll文g卛_
HINSTANCE与HMODULE可以通用
HInstance hinst;
hinst = Loadlibrary("dll2.dll"); //昑ּ加蝲
typedef int (*ADDPROC)(int a , int b); //定义一个函数指?br />ADDPROC Add = (ADDPROC)getprocAdress(hinst, "add"); //获得函数指针
if(!add)
{
messagebox("fail");
}
else
{
CString str;
str.Format("3+5=%d",add(3,5));
MessageBox(str);
}
Sort(int a[],int left,int right)
{
int value,l,r,temp;
l=left;
r=right;
value = a[(left+right)/2];
while(l<r)
{
while(a[l]<value)
l++;
while(a[r]>value)
r--;
if(l>=r)
break;
temp = a[l];
a[l] = a[r];
a[r] = temp;
l++;
r--;
}
if(l==r)
l++;
if(left<r)
Sort(a,left,l-1);
if(l<right)
Sort(a,r+1,right);
}
故ȝ了一下自q使用l验Q以供参考用?/p>
先注明一下,q里Q我们用m_listctrl来表CZ个CListCtrl的类对象Q?/p>
然后q里我们的ListCtrl都是report形式Q至于其他的如什么大图标Q小图标
的暂时不Ԍ毕竟report是大众话的用。其ơ,我们q里用条ƾ一Q条ƾ二
来描q第一点,W二点,q个是参照《Effective C++》的叫法Q俺觉得q么
叫比较COOL :)
条款一Q设|ListCtrl的风?/p>
在CSDN上常常看到有人问怎么讄风格的,他们ListCtrl的样子是一个列?/p>
Q有横条和竖条分界线Q然后选中一行,要整一行都选中Q而不是只有某一?/p>
被选中Q等{,q里l一个比较全面的讄Ҏ?/p>
//获得原有风格
DWORD dwStyle = ::GetWindowLong(m_listctrl.m_hWnd, GWL_STYLE);
dwStyle &= ~(LVS_TYPEMASK);
dwStyle &= ~(LVS_EDITLABELS);
//讄新风?br /> SetWindowLong(m_listctrl.m_hWnd, GWL_STYLE,
dwStyle,|LVS_REPORT|LVS_NOLABELWRAP|LVS_SHOWSELALWAYS);
//讄扩展风格
DWORD styles =
LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES|LVS_EX_CHECKBOXES;
ListView_SetExtendedListViewStyleEx(m_listctrl.m_hWnd, styles,
styles );
其中LVS_EX_FULLROWSELECT 是前面说得整行选中
LVS_EX_GRIDLINES |格U(只适用与report风格的listctrlQ?/p>
LVS_EX_CHECKBOXES 前面加个checkbox
pListCtrl->SetExtendedStyle( m_listctrl.GetExtendedStyle()
|LVS_EX_SUBITEMIMAGES);
q也是一个很重要的属性,q样的话Q可以在列表中加ICONQ记得windows?/p>
d理器吗Q你惛_得那Pq个属性也要加哦,q个我以后会讲的?/p>
条款二:加入列头
q是一个比较实质的东西Q给列表框分列,然后加上列头
代码说话Q来?/p>
TCHAR rgtsz[2][10] = {_T("列头1"), _T("列头2")};
LV_COLUMN lvcolumn;
CRect rect;
m_listctrl.GetWindowRect(&rect);
for(int i=0;i<2;i++)
{
lvcolumn.mask = LVCF_FMT | LVCF_SUBITEM | LVCF_TEXT
| LVCF_WIDTH | LVCF_ORDER;
lvcolumn.fmt = LVCFMT_LEFT;
lvcolumn.pszText = rgtsz[i];
lvcolumn.iSubItem = i;
lvcolumn.iOrder = i;
if(i==0)
{
lvcolumn.cx = rect.Width()*3/5 ;
}
else
lvcolumn.cx = rect.Width()*2/5;
m_listctrl.InsertColumn(i, &lvcolumn);
}
q是插入两列的做法,你要插入20列?Q随便你Q依L葫芦~~
lvcolumn.mask 中那个mask可以有各U属性,具体ȝmsdn吧,
条款三:把记录,插入列表框中
int nIndex = m_listctrl.GetItemCount();
LV_ITEM lvitemAdd = {0};
lvitemAdd.mask = LVIF_TEXT;
lvitemAdd.iItem = nIndex ;
lvitemAdd.iSubItem = 0;
lvitemAdd.pszText =_T("毛毛1");;
if (m_listctrl.InsertItem(&lvitemAdd) != -1)
{
LV_ITEM lvitem = {0};
lvitem.mask = LVIF_TEXT;
lvitem.iItem = nIndex ;
lvitem.iSubItem = 1;
lvitem.pszText =_T("毛毛2");
m_listctrl.SetItem(&lvitem);
}
nIndex 是当前的行数Q然后把新的一行,插在最下面Q?/p>
条款四:l列表中插入图标
在report格式中,也能插入图标
l箋代码说话
m_image是个CImageList对象
m_image.Create(16,16, TRUE|ILC_COLOR24, 3, 1);
m_listctrl.SetImageList(&m_image,LVSIL_SMALL);
然后调用CImageList的成员函数int CImageList::Add( HICON hIcon );
把ICON插入到imagelistQ?/p>
然后在插入记录的时?/p>
lvitemAdd.mask = LVIF_TEXT; Q》 lvitemAdd.mask =
LVIF_TEXT|LVIF_IMAGE
然后d一个lvitemAdd.iImage = n;
q个n是imagelist中的序号Q表C是具体的哪一个图标,list么,呵呵
条款五: 插入记录时用额外的信息QlParam 的?/p>
有时候,你想对于某一行,加入一些额外的信息Q那么就可以使用q个
lParam
msdn是这么描q的Specifies the 32-bit value of the item
我上ơ是Z在某一行加入一个信息,H口句柄Q然后是q么加的Q?/p>
int nIndex = m_listctrl.GetItemCount();
LV_ITEM lvitemAdd = {0};
lvitemAdd.mask = LVIF_TEXT|LVIF_IMAGE|LVIF_PARAM;
lvitemAdd.iItem = nIndex ;
lvitemAdd.iSubItem = 0;
lvitemAdd.pszText =_T("毛毛1");;
lvitemAdd.iImage = n;
lvitemAdd.lParam = (LPARAM)hwnd;(某个H口的窗口句?
if (m_listctrl.InsertItem(&lvitemAdd) != -1)
{
LV_ITEM lvitem = {0};
lvitem.mask = LVIF_TEXT;
lvitem.iItem = nIndex ;
lvitem.iSubItem = 1;
lvitem.pszText =_T("毛毛2");
m_listctrl.SetItem(&lvitem);
}
okQ这是一个比较全的例子的Q又揺CONQ又使用PARAM?/p>
条款六 Q 点击列表框,获取选中行信?/p>
响应NM_CLICK消息Q如果你有MSDNQ可以看刎ͼ有专门关于listview?/p>
NM_CLICK的介l?/p>
void CMyDlg::OnItemClick(NMHDR* pNMHDR, LRESULT* pResult)
{
// TODO: Add your control notification handler code here
int nItem = -1;
LPNMITEMACTIVATE lpNMItemActivate = (LPNMITEMACTIVATE)pNMHDR;
if(lpNMItemActivate != NULL)
{
nItem = lpNMItemActivate->iItem;
}
}
现在nItem是点击选中那行的index了,有了indexQ获取那行的信息q难?/p>
Q?/p>
懒汉_难,因ؓ你还没讲Q晕Q那ql说
条款七: Ҏ行的indexQ获取该行的信息
直接上代码吧
LV_ITEM lvitem = {0};
lvitem.iItem = nIndex;
lvitem.iSubItem = 0;
lvitem.mask = LVIF_TEXT|LVIF_IMAGE|LVIF_PARAM;
m_listctrl.GetItem(&lvitem)
q样Q就把nindex,W一列的信息取出来了Q包括刚才我们加入的ICON,和那?/p>
额外信息Q窗口句柄)Q?/p>
比如我要获取H口句柄Q就可以hwnd = (HWND)lvitem.lParam;
mask 用来指明你想获取那些信息
具体可以查msdn中LVITEM Structure的定义和CListCtrl::GetItem
条款八:用程序选中某一行,使之选中
选中之
m_listctrl.SetItemState
(nIndex,LVIS_SELECTED|LVIS_FOCUSED,LVIS_SELECTED|LVIS_FOCUSED);
不选中Q取消选中?/p>
m_listctrl.SetItemState(nIndex,0,LVIS_SELECTED|LVIS_FOCUSED);
条款九:获取当前所有选中的行Q多选)
q个Q俺比较懒了,抄msdn的代码吧Q反正很?/p>
Example
// CListCtrl* pListCtrl = (CListCtrl*) GetDlgItem
(IDC_YOURLISTCONTROL);
ASSERT(pListCtrl != NULL);
POSITION pos = pList->GetFirstSelectedItemPosition();
if (pos == NULL)
TRACE0("No items were selected!\n");
else
{
while (pos)
{
int nItem = pList->GetNextSelectedItem(pos);
TRACE1("Item %d was selected!\n", nItem);
// you could do your own processing on nItem here
}
}
条款十:删除条款九中选中的行
q个相对前面九个条款是比较麻烦的Q因为如果你要删除多行的话。往往要出?/p>
比如Q我现在要删除第0行和W?行(列表的行序列是从0开始的Q?/p>
那么好啊。我来删?/p>
m_listctrl.DeleteItem(0)
m_listctrl.DeleteItem(1)
恭喜你,错了Q我好开心啊 Q)
因ؓ你删除第0行以后,下面的行会往上移Q那么原来的W?行就变成了第0行,那么你再 m_listctrl.DeleteItem(1)Q那么删除的是原来的W2行,真麻烦,
所以,只有从下往上删Q才是安全的Q先删的Q不会媄响后面的操作Q?/p>
m_listctrl.DeleteItem(1)
m_listctrl.DeleteItem(0)
但有时候,我们也不知道要删除哪些行Q只知道要删除选中的那些行Q像条款九中的那?/p>
如果我们q是?/p>
POSITION pos = m_listctrl.GetFirstSelectedItemPosition();
if (pos == NULL)
TRACE0("No items were selected!\n");
else
{
while (pos)
{
int nItem = m_listctrl.GetNextSelectedItem(pos);
m_listctrl.DeleteItem(nItem );
}
}
你就{着收尸?/p>
q时候我们就要B4微Y了,cx有GetLastselectedItemPosition 和GetPrevSelectedItem
多写一Ҏ员函Cd :(
没办法,办法自己惻Iq里有个W办?/p>
POSITION sSelPos = NULL;
while(sSelPos = m_listctrl.GetFirstSelectedItemPosition())
{
int nSelItem = -1;
nSelItem = m_listctrl.GetNextSelectedItem(sSelPos);
if(nSelItem >= 0 && nSelItem<m_listctrl.GetItemCount())
{
好了Q这个nSelItem 是我们要的DD
}
}
GetNextSelectedItemq个函数Q看msdn的用法,其实是返回第一个的indexQ然后走C一个选中的行去,所以这么做也是安全的,在实际中Q俺也是q么做的Q测试也通过Q没问题?/p>
当然Q还有个办法Q先通过GetFirstSelectedItemPosition和GetNextSelectedItem
来获取所有的选中行的indexQ然后把q些index攑ֈ一个数l里Q然后再从下往上删
唉真ȝ啊,q要不定数组Q不说用new在堆上开吧,那么一个vectorL要的吧,ȝ?/p>
所以我暂时是用上述的办法来删除Q也供大家参考,希望能找到更好的办法?br />
CListCtrl使用技?/font>
以下未经说明Qlistctrl默认view 风格为report
LVS_ICON: 为每个item昄大图?br /> LVS_SMALLICON: 为每个item昄图?br /> LVS_LIST: 昄一列带有小图标的item
LVS_REPORT: 昄item详细资料
直观的理解:windows资源理器,“查看”标{下的“大图标Q小图标Q列表,详细资料?/p>
LONG lStyle;
lStyle = GetWindowLong(m_list.m_hWnd, GWL_STYLE);//获取当前H口style
lStyle &= ~LVS_TYPEMASK; //清除昄方式?br /> lStyle |= LVS_REPORT; //讄style
SetWindowLong(m_list.m_hWnd, GWL_STYLE, lStyle);//讄style
DWORD dwStyle = m_list.GetExtendedStyle();
dwStyle |= LVS_EX_FULLROWSELECT;//选中某行使整行高亮(只适用与report风格的listctrlQ?br /> dwStyle |= LVS_EX_GRIDLINES;//|格U(只适用与report风格的listctrlQ?br /> dwStyle |= LVS_EX_CHECKBOXES;//item前生成checkbox控g
m_list.SetExtendedStyle(dwStyle); //讄扩展风格
注:listview的styleh阅msdn
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wceshellui5/html/wce50lrflistviewstyles.asp
m_list.InsertColumn( 0, "ID", LVCFMT_LEFT, 40 );//插入?br /> m_list.InsertColumn( 1, "NAME", LVCFMT_LEFT, 50 );
int nRow = m_list.InsertItem(0, ?1?;//插入?br /> m_list.SetItemText(nRow, 1, “jacky?;//讄数据
int nIndex = 0;
//选中
m_list.SetItemState(nIndex, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED);
//取消选中
m_list.SetItemState(nIndex, 0, LVIS_SELECTED|LVIS_FOCUSED);
m_list.SetExtendedStyle(LVS_EX_CHECKBOXES);
CString str;
for(int i=0; i<m_list.GetItemCount(); i++)
{
if( m_list.GetItemState(i, LVIS_SELECTED) == LVIS_SELECTED || m_list.GetCheck(i))
{
str.Format(_T("W?d行的checkbox为选中状?), i);
AfxMessageBox(str);
}
}
Ҏ一Q?br /> CString str;
for(int i=0; i<m_list.GetItemCount(); i++)
{
if( m_list.GetItemState(i, LVIS_SELECTED) == LVIS_SELECTED )
{
str.Format(_T("选中了第%d?), i);
AfxMessageBox(str);
}
}
Ҏ二:
POSITION pos = m_list.GetFirstSelectedItemPosition();
if (pos == NULL)
TRACE0("No items were selected!\n");
else
{
while (pos)
{
int nItem = m_list.GetNextSelectedItem(pos);
TRACE1("Item %d was selected!\n", nItem);
// you could do your own processing on nItem here
}
}
TCHAR szBuf[1024];
LVITEM lvi;
lvi.iItem = nItemIndex;
lvi.iSubItem = 0;
lvi.mask = LVIF_TEXT;
lvi.pszText = szBuf;
lvi.cchTextMax = 1024;
m_list.GetItem(&lvi);
关于得到讄item的状态,q可以参考msdn文章
Q173242: Use Masks to Set/Get Item States in CListCtrl
http://support.microsoft.com/kb/173242/en-us
LVCOLUMN lvcol;
char str[256];
int nColNum;
CString strColumnName[4];//假如??/p>
nColNum = 0;
lvcol.mask = LVCF_TEXT;
lvcol.pszText = str;
lvcol.cchTextMax = 256;
while(m_list.GetColumn(nColNum, &lvcol))
{
strColumnName[nColNum] = lvcol.pszText;
nColNum++;
}
Ҏ一Q?br /> while ( m_list.DeleteColumn (0))
因ؓ你删除了W一列后Q后面的列会依次向上Ud?/p>
Ҏ二:
int nColumns = 4;
for (int i=nColumns-1; i>=0; i--)
m_list.DeleteColumn (i);
dlistctrl控g的NM_CLICK消息相应函数
void CTest6Dlg::OnClickList1(NMHDR* pNMHDR, LRESULT* pResult)
{
// Ҏ一Q?br /> /*
DWORD dwPos = GetMessagePos();
CPoint point( LOWORD(dwPos), HIWORD(dwPos) );
m_list.ScreenToClient(&point);
LVHITTESTINFO lvinfo;
lvinfo.pt = point;
lvinfo.flags = LVHT_ABOVE;
int nItem = m_list.SubItemHitTest(&lvinfo);
if(nItem != -1)
{
CString strtemp;
strtemp.Format("单击的是W?d行第%d?, lvinfo.iItem, lvinfo.iSubItem);
AfxMessageBox(strtemp);
}
*/
// Ҏ?
/*
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
if(pNMListView->iItem != -1)
{
CString strtemp;
strtemp.Format("单击的是W?d行第%d?,
pNMListView->iItem, pNMListView->iSubItem);
AfxMessageBox(strtemp);
}
*/
*pResult = 0;
}
dlistctrl控g的NM_CLICK消息相应函数
void CTest6Dlg::OnClickList1(NMHDR* pNMHDR, LRESULT* pResult)
{
DWORD dwPos = GetMessagePos();
CPoint point( LOWORD(dwPos), HIWORD(dwPos) );
m_list.ScreenToClient(&point);
LVHITTESTINFO lvinfo;
lvinfo.pt = point;
lvinfo.flags = LVHT_ABOVE;
UINT nFlag;
int nItem = m_list.HitTest(point, &nFlag);
//判断是否点在checkbox?br /> if(nFlag == LVHT_ONITEMSTATEICON)
{
AfxMessageBox("点在listctrl的checkbox?);
}
*pResult = 0;
}
dlistctrl控g的NM_RCLICK消息相应函数
void CTest6Dlg::OnRclickList1(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
if(pNMListView->iItem != -1)
{
DWORD dwPos = GetMessagePos();
CPoint point( LOWORD(dwPos), HIWORD(dwPos) );
CMenu menu;
VERIFY( menu.LoadMenu( IDR_MENU1 ) );
CMenu* popup = menu.GetSubMenu(0);
ASSERT( popup != NULL );
popup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this );
}
*pResult = 0;
}
dlistctrl控g的LVN_ITEMCHANGED消息相应函数
void CTest6Dlg::OnItemchangedList1(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
// TODO: Add your control notification handler code here
CString sTemp;
if((pNMListView->uOldState & LVIS_FOCUSED) == LVIS_FOCUSED &&
(pNMListView->uNewState & LVIS_FOCUSED) == 0)
{
sTemp.Format("%d losted focus",pNMListView->iItem);
}
else if((pNMListView->uOldState & LVIS_FOCUSED) == 0 &&
(pNMListView->uNewState & LVIS_FOCUSED) == LVIS_FOCUSED)
{
sTemp.Format("%d got focus",pNMListView->iItem);
}
if((pNMListView->uOldState & LVIS_SELECTED) == LVIS_SELECTED &&
(pNMListView->uNewState & LVIS_SELECTED) == 0)
{
sTemp.Format("%d losted selected",pNMListView->iItem);
}
else if((pNMListView->uOldState & LVIS_SELECTED) == 0 &&
(pNMListView->uNewState & LVIS_SELECTED) == LVIS_SELECTED)
{
sTemp.Format("%d got selected",pNMListView->iItem);
}
*pResult = 0;
}
http://www.codeguru.com/cpp/controls/listview/introduction/article.php/c919/
m_list.SetExtendedStyle(LVS_EX_SUBITEMIMAGES);
m_list.SetItem(..); //具体参数请参考msdn
|上扑ֈ的代码,share
BOOL CTest6Dlg::OnInitDialog()
{
CDialog::OnInitDialog();
HIMAGELIST himlSmall;
HIMAGELIST himlLarge;
SHFILEINFO sfi;
char cSysDir[MAX_PATH];
CString strBuf;
memset(cSysDir, 0, MAX_PATH);
GetWindowsDirectory(cSysDir, MAX_PATH);
strBuf = cSysDir;
sprintf(cSysDir, "%s", strBuf.Left(strBuf.Find("\\")+1));
himlSmall = (HIMAGELIST)SHGetFileInfo ((LPCSTR)cSysDir,
0,
&sfi,
sizeof(SHFILEINFO),
SHGFI_SYSICONINDEX | SHGFI_SMALLICON );
himlLarge = (HIMAGELIST)SHGetFileInfo((LPCSTR)cSysDir,
0,
&sfi,
sizeof(SHFILEINFO),
SHGFI_SYSICONINDEX | SHGFI_LARGEICON);
if (himlSmall && himlLarge)
{
::SendMessage(m_list.m_hWnd, LVM_SETIMAGELIST,
(WPARAM)LVSIL_SMALL, (LPARAM)himlSmall);
::SendMessage(m_list.m_hWnd, LVM_SETIMAGELIST,
(WPARAM)LVSIL_NORMAL, (LPARAM)himlLarge);
}
return TRUE; // return TRUE unless you set the focus to a control
}
void CTest6Dlg::AddFiles(LPCTSTR lpszFileName, BOOL bAddToDocument)
{
int nIcon = GetIconIndex(lpszFileName, FALSE, FALSE);
CString strSize;
CFileFind filefind;
// get file size
if (filefind.FindFile(lpszFileName))
{
filefind.FindNextFile();
strSize.Format("%d", filefind.GetLength());
}
else
strSize = "0";
// split path and filename
CString strFileName = lpszFileName;
CString strPath;
int nPos = strFileName.ReverseFind('\\');
if (nPos != -1)
{
strPath = strFileName.Left(nPos);
strFileName = strFileName.Mid(nPos + 1);
}
// insert to list
int nItem = m_list.GetItemCount();
m_list.InsertItem(nItem, strFileName, nIcon);
m_list.SetItemText(nItem, 1, strSize);
m_list.SetItemText(nItem, 2, strFileName.Right(3));
m_list.SetItemText(nItem, 3, strPath);
}
int CTest6Dlg::GetIconIndex(LPCTSTR lpszPath, BOOL bIsDir, BOOL bSelected)
{
SHFILEINFO sfi;
memset(&sfi, 0, sizeof(sfi));
if (bIsDir)
{
SHGetFileInfo(lpszPath,
FILE_ATTRIBUTE_DIRECTORY,
&sfi,
sizeof(sfi),
SHGFI_SMALLICON | SHGFI_SYSICONINDEX |
SHGFI_USEFILEATTRIBUTES |(bSelected ? SHGFI_OPENICON : 0));
return sfi.iIcon;
}
else
{
SHGetFileInfo (lpszPath,
FILE_ATTRIBUTE_NORMAL,
&sfi,
sizeof(sfi),
SHGFI_SMALLICON | SHGFI_SYSICONINDEX |
SHGFI_USEFILEATTRIBUTES | (bSelected ? SHGFI_OPENICON : 0));
return sfi.iIcon;
}
return -1;
}
m_list.SetRedraw(FALSE);
//更新内容
m_list.SetRedraw(TRUE);
m_list.Invalidate();
m_list.UpdateWindow();
或者参?
Q250614QHow To Sort Items in a CListCtrl in Report View
http://support.microsoft.com/kb/250614/en-us
Q151897: CListCtrl::InsertColumn() Causes Column Data to Shift
http://support.microsoft.com/kb/151897/en-us
解决办法Q把W一列当一个虚列,从第二列开始插入列及数据,最后删除第一列?br />
具体解释参阅 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/commctls/listview/structures/lvcolumn.asp
http://msdn.microsoft.com/msdnmag/issues/03/06/CQA/
把需隐藏的列的宽度设?,然后当该列为隐藏列Ӟ用上面第27点的锁定column 的拖动来实现
http://www.codeguru.com/cpp/controls/listview/advanced/article.php/c4151/
http://www.codeproject.com/listctrl/virtuallist.asp
解决办法Q需要在item上放一个edit?br />
Q125694: How To Find Out Which Listview Column Was Right-Clicked
http://support.microsoft.com/kb/125694/en-us
Q234310: How to implement a ListView control that is similar to Windows Explorer by using DirLV.exe
http://support.microsoft.com/kb/234310/en-us
Q200054Q?br />PRB: OnTimer() Is Not Called Repeatedly for a List Control
http://support.microsoft.com/kb/200054/en-us
(1) 拖放
http://www.codeproject.com/listctrl/dragtest.asp
在CListCtrl和CTreeCtrl间拖?/span>
http://support.microsoft.com/kb/148738/en-us
(2) 多功能listctrl
支持subitem可编辑,图标QradiobuttonQcheckboxQ字W串改变颜色的类
http://www.codeproject.com/listctrl/quicklist.asp
支持排序Qsubitem可编辑,subitem图标Qsubitem改变颜色的类
http://www.codeproject.com/listctrl/ReportControl.asp
(3) subitem中显C链接
http://www.codeproject.com/listctrl/CListCtrlLink.asp
(4) subitem的tooltip提示
http://www.codeproject.com/listctrl/ctooltiplistctrl.asp
(5) subitem中显C度条
http://www.codeproject.com/listctrl/ProgressListControl.asp
http://www.codeproject.com/listctrl/napster.asp
http://www.codeguru.com/Cpp/controls/listview/article.php/c4187/
(6) 动态改变subitem的颜色和背景?/span>
http://www.codeproject.com/listctrl/highlightlistctrl.asp
http://www.codeguru.com/Cpp/controls/listbox/colorlistboxes/article.php/c4757/
(7) cvb属性对话框
http://www.codeproject.com/listctrl/propertylistctrl.asp
http://www.codeguru.com/Cpp/controls/listview/propertylists/article.php/c995/
http://www.codeguru.com/Cpp/controls/listview/propertylists/article.php/c1041/
(8) 选中subitem(只高亮选中的item)
http://www.codeproject.com/listctrl/SubItemSel.asp
http://www.codeproject.com/listctrl/ListSubItSel.asp
(9) 改变行高
http://www.codeproject.com/listctrl/changerowheight.asp
(10) 改变行颜?/span>
http://www.codeproject.com/listctrl/coloredlistctrl.asp
(11) 可编辑subitem的listctrl
http://www.codeproject.com/listctrl/nirs2000.asp
http://www.codeproject.com/listctrl/editing_subitems_in_listcontrol.asp
(12) subitem可编辑,插入comboboxQ改变行颜色Qsubitem的tooltip提示
http://www.codeproject.com/listctrl/reusablelistcontrol.asp
(13) header 中允许多行字W串
http://www.codeproject.com/listctrl/headerctrlex.asp
(14) 插入combobox
http://www.codeguru.com/Cpp/controls/listview/editingitemsandsubitem/article.php/c979/
(15) d背景囄
http://www.codeguru.com/Cpp/controls/listview/backgroundcolorandimage/article.php/c4173/
http://www.codeguru.com/Cpp/controls/listview/backgroundcolorandimage/article.php/c983/
http://www.vchelp.net/vchelp/archive.asp?type_id=9&class_id=1&cata_id=1&article_id=1088&search_term=
(16) 自适应宽度的listctrl
http://www.codeproject.com/useritems/AutosizeListCtrl.asp
http://www.codeproject.com/listctrl/lvcustomdraw.asp
OnDestroy()Q消息响应函敎ͼ响应WM_DESTROY消息Q当一个窗口即被销毁时Q被发?/p>
在单视图E序?Ҏ<<深入出MFC>>所?E序退出时执行的操作顺序ؓ
(1)用户点击退出按?发送了WM_CLOSE消息
(2)在WM_CLOSE消息的处理函C,调用DestroyWindow()
(3)在DestroyWindow()中发送了WM_DESTROY消息
(4)在WM_DESTROY消息中调用PostQuitMessage(),发送WM_QUIT消息,l束消息循环
lgQ程序先调用OnClose()Q也可能不调用)Q然后调用OnDestroy()Q必调用Q,所以,如果要进行程序结束时的清理工作,应该在OnDestroyQ)中,而不是在OnClose()Q否则就有可能会出现内存泄漏的危险了Q?/p>
struct a
{
int b;
};
struct b
{
int a;
};
void main()
{
a A;
A.b = NULL;
A.b = 1;
b a;
a.a = 3;
}
在C的环境下Q会报错Q在C++的情况,q样的操作就是允许的?br />在C++的编译器中,允许结构体名作Z个变量名来对待?/p>