当前位置:文档之家› MFC ListBox控件用法介绍

MFC ListBox控件用法介绍

MFC ListBox控件用法介绍
MFC ListBox控件用法介绍

MFC CListCtrl 使用介绍

列表控件可以看作是功能增强的ListBox,它提供了四种风格,而且可以同时显示一列的多中属性值。MFC中使用CListCtrl类来封装列表控件的各种操作。通过调用

BOOL Create( DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID );创建一个窗口,dwStyle中可以使用以下一些列表控件的专用风格:

?LVS_ICON LVS_SMALLICON LVS_LIST LVS_REPORT 这四种风格决定控件的外观,同时只可以选择其中一种,分别对应:大图标显示,小图标显示,列表显示,详细报表显示

?LVS_EDITLABELS 结点的显示字符可以被编辑,对于报表风格来讲可编辑的只为第一列。

?LVS_SHOWSELALWAYS 在失去焦点时也显示当前选中的结点

?LVS_SINGLESEL 同时只能选中列表中一项

首先你需要设置列表控件所使用的ImageList,如果你使用大图标显示风格,你就需要以如下形式调用:

CImageList* SetImageList( CImageList* pImageList, LVSIL_NORMAL);

如果使用其它三种风格显示而不想显示图标你可以不进行任何设置,否则需要以如下形式调用:

CImageList* SetImageList( CImageList* pImageList, LVSIL_SMALL);

通过调用int InsertItem( int nItem, LPCTSTR lpszItem );可以在列表控件中nItem指明位置插入一项,lpszItem为显示字符。除LVS_REPORT风格外其他三种风格都只需要直接调用InsertItem就可以了,但如果使用报表风格就必须先设置列表控件中的列信息。

通过调用int InsertColumn( int nCol, LPCTSTR lpszColumnHeading, int nFormat , int nWidth, int nSubItem);可以插入列。iCol为列的位置,从零开始,lpszColumnHeading为显示的列名,nFormat为显示对齐方式,nWidth为显示宽度,nSubItem为分配给该列的列索引。

在有多列的列表控件中就需要为每一项指明其在每一列中的显示字符,通过调用

BOOL SetItemText( int nItem, int nSubItem, LPTSTR lpszText );可以设置每列的显示字符。nItem为设置的项的位置,nSubItem为列位置,lpszText为显示字符。下面的代码演示了如何设置多列并插入数据:

m_list.SetImageList(&m_listSmall,LVSIL_SMALL);//设置ImageList

m_list.InsertColumn(0,"Col 1",LVCFMT_LEFT,300,0);//设置列

m_list.InsertColumn(1,"Col 2",LVCFMT_LEFT,300,1);

m_list.InsertColumn(2,"Col 3",LVCFMT_LEFT,300,2);

m_list.InsertItem(0,"Item 1_1");//插入行

m_list.SetItemText(0,1,"Item 1_2");//设置该行的不同列的显示字符

m_list.SetItemText(0,2,"Item 1_3");

此外CListCtrl还提供了一些函数用于得到/修改控件的状态。

COLORREF GetTextColor( )/BOOL SetTextColor( COLORREF cr );用于得到/设置显示的

字符颜色。

COLORREF GetTextBkColor( )/BOOL SetTextBkColor( COLORREF cr );用于得到/设置显示的背景颜色。

void SetItemCount( int iCount );用于得到添加进列表中项的数量。

BOOL DeleteItem(int nItem);用于删除某一项,BOOL DeleteAllItems( );将删除所有项。BOOL SetBkImage(HBITMAP hbm, BOOL fTile , int xOffsetPercent, int yOffsetPercent);用于设置背景位图。

CString GetItemText( int nItem, int nSubItem );用于得到某项的显示字符。

列表控件的消息映射同样使用ON_NOTIFY宏,形式如同:ON_NOTIFY( wNotifyCode, id, memberFxn ),wNotifyCode为通知代码,id为产生该消息的窗口ID,memberFxn为处理函数,函数的原型如同void OnXXXList(NMHDR* pNMHDR, LRESULT* pResult),其中pNMHDR为一数据结构,在具体使用时需要转换成其他类型的结构。对于列表控件可能取值和对应的数据结构为:

?LVN_BEGINLABELEDIT 在开始某项编辑字符时发送,所用结构:NMLVDISPINF O

?LVN_ENDLABELEDIT 在结束某项编辑字符时发送,所用结构:NMLVDISPINFO

?LVN_GETDISPINFO 在需要得到某项信息时发送,(如得到某项的显示字符)所用结构:NMLVDISPINFO

关于ON_NOTIFY有很多内容,将在以后的内容中进行详细讲解。

关于动态提供结点所显示的字符:首先你在项时需要指明lpszItem参数为:

LPSTR_TEXTCALLBACK。在控件显示该结点时会通过发送TVN_GETDISPINFO来取得所需要的字符,在处理该消息时先将参数pNMHDR转换为LPNMLVDISPINFO,然后填充其中item.pszText。通过item中的iItem,iSubItem可以知道当前显示的为那一项。下面的代码演示了这种方法:

char szOut[8][3]={"No.1","No.2","No.3"};

//添加结点

m_list.InsertItem(LPSTR_TEXTCALLBACK,...)

m_list.InsertItem(LPSTR_TEXTCALLBACK,...)

//处理消息

void CParentWnd::OnGetDispInfoList(NMHDR* pNMHDR, LRESULT* pResult)

{

LV_DISPINFO* pLVDI = (LV_DISPINFO*)pNMHDR;

pLVDI->item.pszText=szOut[pTVDI->item.iItem];//通过iItem得到需要显示的字符在数组中的位置

*pResult = 0;

}

关于编辑某项的显示字符:(在报表风格中只对第一列有效)首先需要设置列表控件的LVS_EDITLABELS风格,在开始编辑时该控件将会发送LVN_BEGINLABELEDIT,你可以通过在处理函数中返回TRUE来取消接下来的编辑,在编辑完成后会发送

{

str.Format(_T("第%d行的checkbox为选中状态"), i);

AfxMessageBox(str);

}

}

7. 得到listctrl中所有选中行的序号

方法一:

CString str;

for(int i=0; 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

}

}

8. 得到item的信息

TCHAR szBuf[1024];

LVITEM lvi;

lvi.iItem = nItemIndex;

lvi.iSubItem = 0;

lvi.mask = LVIF_TEXT;

lvi.pszText = szBuf;

https://www.doczj.com/doc/7215806662.html,hTextMax = 1024;

m_list.GetItem(&lvi);

// 方法一:

/*

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("单击的是第%d行第%d列", lvinfo.iItem, lvinfo.iSubItem);

AfxMessageBox(strtemp);

}

*/

// 方法二:

/*

NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;

if(pNMListView->iItem != -1)

{

CString strtemp;

strtemp.Format("单击的是第%d行第%d列",

pNMListView->iItem, pNMListView->iSubItem);

AfxMessageBox(strtemp);

}

*/

*pResult = 0;

}

14. 判断是否点击在listctrl的checkbox上

添加listctrl控件的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上

if(nFlag == LVHT_ONITEMSTATEICON)

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;

}

转自:https://www.doczj.com/doc/7215806662.html,/share/detail/21176843

VC CListCtrl的使用完全指南

2008-04-12 14:46

创建图形列表并和CListCtrl关联:

m_image_list.Create(IDB_CALLER2, 16, 10, RGB(192,192, 192));

m_image_list.SetBkColor( GetSysColor( COLOR_WINDOW ) );

m_caller_list.SetImageList( &m_image_list, LVSIL_SMALL);

为报表添加4列:

char *szColumn[]={"昵称","IP地址","登陆时间","状态"};

int widths[]={100,98,70,55};

LV_COLUMN lvc;

lvc.mask=LVCF_FMT|LVCF_WIDTH|LVCF_TEXT|LVCF_SUBITEM;

lvc.fmt=LVCFMT_LEFT;

for(int i=0;i<4;i++) {//插入各列

lvc.pszText=szColumn[i];

lvc.cx=widths[i];

lvc.iSubItem=i;

m_caller_list.InsertColumn(i,&lvc);

}

为报表添加两项,以附加方式添加:

char* data[4];

data[0]="所有人";

data[1]="0.0.0.0";

data[3]="在线";

data[2]=new char;

CTime now=CTime::GetCurrentTime();

CString temp = now.Format("%H:%M:%S");

data[2]=temp.GetBuffer(1);

LV_ITEM lvi;

lvi.mask=LVIF_TEXT|LVIF_IMAGE|LVIF_PARAM;

lvi.iSubItem=0;

lvi.pszText=(char *)data[0];

lvi.iImage = 0;

lvi.iItem=0;

m_caller_list.InsertItem(&lvi);

for (int j=0;j<4;j++) m_caller_list.SetItemText(count,j,data[j]);

count++;

lvi.iImage = 1;

lvi.iItem=count;

m_caller_list.InsertItem(&lvi);

data[0]="cherami";

data[1]="127.0.0.1";

for (int n=0;n<4;n++) m_caller_list.SetItemText(count,n,data[n]);

count++;

设置报表的样式

选中一整行:

m_list_ctrl.SetExtendedStyle(m_list_ctrl.GetExtendedStyle()|LVS_EX_FULLROWSELEC T);

绘制表格:

m_list_ctrl.SetExtendedStyle(m_list_ctrl.GetExtendedStyle()|LVS_EX_GRIDLINES);

带复选框:

m_list_ctrl.SetExtendedStyle(m_list_ctrl.GetExtendedStyle()|LVS_EX_CHECKBOXES); 自动切换:

m_list_ctrl.SetExtendedStyle(m_list_ctrl.GetExtendedStyle()|LVS_EX_TRACKSELECT); 选定一行:

设置CListCtrl的Show selection always选项

SetItemState (iIndex, LVIS_SELECTED|LVIS_FOCUSED,

LVIS_SELECTED|LVIS_FOCUSED)

选中一个或多个项目时,会发送LVN_ITEMCHANGED消息,可以使用GetSelectedCount()方法得到被选定的项的数目。

点击列头的消息响应:

ON_NOTIFY(HDN_ITEMCLICKW, 0, ResponseFunc)

消息,需要自己添加

或者:

ON_NOTIFY(LVN_COLUMNCLICK, ID_yourCtrl, ResponseFunc)//向导添加

前者后响应,后者先响应

响应函数:

ResponseFunc(NMHDR *pNMHDR, LRESULT *pResult)

双击CListCtrl中的ITEM的消息是及消息函数:

ON_NOTIFY(NM_DBLCLK, ID_yourCtrl, ResponseFunc)

单击ITEM的消息响应:

ON_NOTIFY(NM_CLICK, ID_yourCtrl, ResponseFunc)

ResponseFunc(NMHDR *pNMHDR, LRESULT *pResult)

HDN_ITEMCLICK 就是Header control Notify message for mouse left click on the Header control!

而HDN_ITEMCLICK是当List View中存在一个Header Contrl时,Header Ctrl通知父窗口List View的!

CListCtrl中的Item被选中触发LBN_SELCHANGE(通过WM_COMMAND)消息!

删除CListCtrl中选定的项:

POSITION pos;

int nIndex;

for(; pos= GetFirstSelectedItemPosition();)

{

nIndex = GetNextSelectedItem(pos);

DeleteItem(nIndex);

}

在ListCtrl中进行排序

列表控件(CListCtrl)的顶部有一排按钮,用户可以通过选择不同的列来对记录进行排序。但是CListCtrl并没有自动排序的功能,我们需要自己添加一个用于排序的回调函数来比较两个数据的大小,此外还需要响应排序按钮被点击的消息。下面讲述一下具体的做法。

CListCtrl提供了用于排序的函数,函数原型为:BOOL

CListCtrl::SortItems( PFNLVCOMPARE pfnCompare, DWORD dwData )。其中第一个参数为全局排序函数的地址,第二个参数为用户数据,你可以根据你的需要传递一个数据或是

指针。该函数返回-1代表第一项排应在第二项前面,返回1代表第一项排应在第二项后面,返回0代表两项相等。

用于排序的函数原形为:int CALLBACK ListCompare(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort),其中第三个参数为调用者传递的数据(即调用SortItems 时的第二个参数dwData)。第一和第二个参数为用于比较的两项的ItemData,你可以通过DWORD CListCtrl::GetItemData( int nItem )/BOOL CListCtrl::SetItemData( int nItem, DWORD dwData )来对每一项的ItemData进行存取。在添加项时选用特定的CListCtrl::InsertItem也可以设置该值。由于你在排序时只能通过该值来确定项的位置所以你应该比较明确的确定该值的含义。

最后一点,我们需要知道什么时候需要排序,实现这点可以在父窗口中对

LVN_COLUMNCLICK消息进行处理来实现。

下面我们看一个例子,这个例子是一个派生类,并支持顺序/倒序两种方式排序。为了简单我对全局数据进行排序,而在实际应用中会有多组需要排序的数据,所以需要通过传递参数的方式来告诉派序函数需要对什么数据进行排序。

//全局数据

struct DEMO_DATA

{

char szName[20];

int iAge;

}strAllData[5]={{"王某",30},{"张某",40},{"武某",32},{"陈某",20},{"李某",36}};

//CListCtrl派生类定义

class CSortList : public CListCtrl

{

// Construction

public:

CSortList();

BOOL m_fAsc;//是否顺序排序

int m_nSortedCol;//当前排序的列

protected:

//{{AFX_MSG(CSortList)

//}}AFX_MSG

...

};

//父窗口中包含该CListCtrl派生类对象

class CSort_in_list_ctrlDlg : public CDialog

{

// Construction

public:

CSort_in_list_ctrlDlg(CWnd* pParent = NULL); // standard constructor

// Dialog Data

//{{AFX_DATA(CSort_in_list_ctrlDlg)

enum { IDD = IDD_SORT_IN_LIST_CTRL_DIALOG };

CSortList m_listTest;

//}}AFX_DATA

}

//在父窗口中定义LVN_COLUMNCLICK消息映射

BEGIN_MESSAGE_MAP(CSort_in_list_ctrlDlg, CDialog)

//{{AFX_MSG_MAP(CSort_in_list_ctrlDlg)

ON_NOTIFY(LVN_COLUMNCLICK, IDC_LIST1, OnColumnclickList1)

//}}AFX_MSG_MAP

END_MESSAGE_MAP()

//初始化数据

BOOL CSort_in_list_ctrlDlg::OnInitDialog()

{

CDialog::OnInitDialog();

//初始化ListCtrl中数据列表

m_listTest.InsertColumn(0,"姓名");

m_listTest.InsertColumn(1,"年龄");

m_listTest.SetColumnWidth(0,80);

m_listTest.SetColumnWidth(1,80);

for(int i=0;i<5;i++)

{

m_listTest.InsertItem(i,strAllData[i].szName);

char szAge[10];

sprintf(szAge,"%d",strAllData[i].iAge);

m_listTest.SetItemText(i,1,szAge);

//设置每项的ItemData为数组中数据的索引

//在排序函数中通过该ItemData来确定数据

m_listTest.SetItemData(i,i);

}

return TRUE; // return TRUE unless you set the focus to a control

}

//处理消息

void CSort_in_list_ctrlDlg::OnColumnclickList1(NMHDR* pNMHDR, LRESULT* pResult) {

NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;

//设置排序方式

if( pNMListView->iSubItem == m_listTest.m_nSortedCol )

m_listTest.m_fAsc = !m_listTest.m_fAsc;

else

{

m_listTest.m_fAsc = TRUE;

m_listTest.m_nSortedCol = pNMListView->iSubItem;

}

//调用排序函数

m_listTest.SortItems( ListCompare, (DWORD)&m_listTest );

*pResult = 0;

}

//排序函数实现

int CALLBACK ListCompare(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)

{

//通过传递的参数来得到CSortList对象指针,从而得到排序方式

CSortList* pV=(CSortList*)lParamSort;

//通过ItemData来确定数据

DEMO_DATA* pInfo1=strAllData+lParam1;

DEMO_DATA* pInfo2=strAllData+lParam2;

CString szComp1,szComp2;

int iCompRes;

switch(pV->m_nSortedCol)

{

case(0):

//以第一列为根据排序

szComp1=pInfo1->szName;

szComp2=pInfo2->szName;

iCompRes=https://www.doczj.com/doc/7215806662.html,pare(szComp2);

break;

case(1):

//以第二列为根据排序

if(pInfo1->iAge == pInfo2->iAge)

iCompRes = 0;

else

iCompRes=(pInfo1->iAge < pInfo2->iAge)?-1:1;

break;

default:

ASSERT(0);

break;

}

//根据当前的排序方式进行调整

if(pV->m_fAsc)

return iCompRes;

else

return iCompRes*-1;

}

排序最快:

CListCtrl::SortItems

Example

// Sort the item in reverse alphabetical order.

static int CALLBACK

MyCompareProc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)

{

// lParamSort contains a pointer to the list view control.

// The lParam of an item is just its index.

CListCtrl* pListCtrl = (CListCtrl*) lParamSort;

CString strItem1 = pListCtrl->GetItemText(lParam1, 0);

CString strItem2 = pListCtrl->GetItemText(lParam2, 0);

return strcmp(strItem2, strItem1);

}

void snip_CListCtrl_SortItems()

{

// The pointer to my list view control.

extern CListCtrl* pmyListCtrl;

// Sort the list view items using my callback procedure.

pmyListCtrl->SortItems(MyCompareProc, (LPARAM) pmyListCtrl);

}

If you don’t want to allow the users to sort the list by clicking on the header, you can use the style LVS_NOSORTHEADER. However, if you do want to allow sorting, you do not specify the LVS_NOSORTHEADER. The control, though, does not sort the items. You have to handle the HDN_ITEMCLICK notification from the header control and process it appropriately. In the code below, we have used the sorting function SortTextItems() developed in a previous section. You may choose to sort the items in a different manner. Step 1: Add two member variables

Add two member variables to the CListCtrl. The first variable to track which column has been sorted on, if any. The second variable to track if the sort is ascending or descending.

int nSortedCol;

BOOL bSortAscending;

Step 2: Initialize them in the constructor.

Initialize nSortedCol to -1 to indicate that no column has been sorted on. If the list is initially sorted, then this variable should reflect that.

nSortedCol = -1;

bSortAscending = TRUE;

Step 3: Add entry in message map to handle HDN_ITEMCLICK

Actually you need to add two entries. For HDN_ITEMCLICKA and HDN_ITEMCLICKW. Do not use the class wizard to add the entry. For one, you need to add two entries whereas the class wizard will allow you only one. Secondly, the class wizard uses the wrong macro in the entry. It uses ON_NOTIFY_REFLECT() instead of ON_NOTIFY(). Since the HDN_ITEMCLICK is a notification from the header control to the list view control, it is a direct notification and not a reflected one.

ON_NOTIFY(HDN_ITEMCLICKA, 0, OnHeaderClicked)

ON_NOTIFY(HDN_ITEMCLICKW, 0, OnHeaderClicked)

Note that we specify the same function for both the notification. Actually the program will receive one or the other and not both. What notification it receives will depend on the OS. The list view control on Windows 95 will send the ANSI version and the control on NT will

send the UNICODE version.

Also, note that the second argument is zero. This value filters for the id of the control and we know that header control id is zero.

Step 4: Write the OnHeaderClicked() function

Here’s where you decide what to do when the user clicks on a column header. The expected behaviour is to sort the list based on the values of the items in that column. In this function we have used the SortTextItems() function developed in a previous section. If any of the columns displays numeric or date values, then you would have to provide custom sorting for them.

void CMyListCtrl::OnHeaderClicked(NMHDR* pNMHDR, LRESULT* pResult)

{

HD_NOTIFY *phdn = (HD_NOTIFY *) pNMHDR;

if( phdn->iButton == 0 )

{

// User clicked on header using left mouse button

if( phdn->iItem == nSortedCol )

bSortAscending = !bSortAscending;

else

bSortAscending = TRUE;

nSortedCol = phdn->iItem;

SortTextItems( nSortedCol, bSortAscending );

}

*pResult = 0;

}

让CListCtrl的SubItem也具有编辑功能:

要重载一个文本框,然后在LVN_BEGINLABELEDIT时改变文本框位置。

CInEdit m_InEdit;

if( ( GetStyle() & LVS_TYPEMASK ) == LVS_REPORT && ( m_nEditSubItem != 0 ) ) {

HWND hwndEdit;

CRect rtBound;

CString strText;

hwndEdit = (HWND)SendMessage( LVM_GETEDITCONTROL );

GetSubItemRect( pDispInfo->item.iItem, m_nEditSubItem, LVIR_LABEL, rtBound );

m_InEdit.SubclassWindow( hwndEdit );

m_InEdit.m_left = rtBound.left;

strText = GetItemText( pDispInfo->item.iItem, m_nEditSubItem );

m_InEdit.SetWindowText( strText );

}

void CInEdit::OnWindowPosChanging(WINDOWPOS FAR* lpwndpos)

{

CRect rtClient;

lpwndpos->x = m_left; // m_left在LVN_BEGINLABELEDIT中设置

CEdit::OnWindowPosChanging(lpwndpos);

// TODO: Add your message handler code here

}

导出数据为excel文件

使用ODBC将数据输出到excel数据区

void ExportAsExcel(CString filename,CListCtrl &resultlist,CWnd * wnd)

{

CDatabase database;

CString sDriver = "MICROSOFT EXCEL DRIVER (*.XLS)"; // Excel安装驱动

CString sSql,sExcelFile;

//弹出对话框选择路径

CFileDialog fileDlg (FALSE, "Path", filename,OFN_FILEMUSTEXIST|

OFN_HIDEREADONLY, "*.xls",wnd);

if( fileDlg.DoModal()==IDOK)

{

sExcelFile = fileDlg.GetPathName(); // 要建立的Excel文件

CFileFind finder;

BOOL bWorking = finder.FindFile(sExcelFile);//寻找文件

if (bWorking)//如果已经存在文件,则删除

{

CFile::Remove((LPCTSTR)sExcelFile);

}

}

else return;

TRY

{

// 创建进行存取的字符串

sSql.Format("DRIVER={%s};DSN='';FIRSTROWHASNAMES=1;READONLY=FALSE; CREATE_DB=\"%s\";DBQ=%s",sDriver, sExcelFile, sExcelFile);

// 创建数据库(既Excel表格文件)

if( database.OpenEx(sSql,CDatabase::noOdbcDialog) )

{

CHeaderCtrl* pHeader = resultlist.GetHeaderCtrl();

//获得行,列的个数

int nColCount = pHeader->GetItemCount();

int nLineCount = resultlist.GetItemCount();

int ColOrderArray[100];

CString ca[100];

resultlist.GetColumnOrderArray(ColOrderArray, nColCount);

//检索各列的信息,确定列标题的内容

for(int i =0 ; i< nColCount; i++)

{

LVCOLUMN lvc;

char text[100];

lvc.mask = LVCF_TEXT|LVCF_SUBITEM;

lvc.pszText = text;

https://www.doczj.com/doc/7215806662.html,hTextMax = 100;

resultlist.GetColumn(ColOrderArray[i], &lvc);

ca[i] = lvc.pszText;

}

// 创建表结构

CString tempsql="(";

for(i =0 ; i< nColCount-1; i++)

{

tempsql+=ca[i];

tempsql+=" TEXT,";

}

tempsql+=ca[nColCount-1];

tempsql+=" TEXT)";

sSql = "CREATE TABLE Sheet1 ";

sSql+=tempsql;

database.ExecuteSQL(sSql);

//插入数据

int item_count=resultlist.GetItemCount();

tempsql="(";

for(i =0 ; i< nColCount-1; i++)

{

tempsql+=ca[i];

tempsql+=" ,";

}

tempsql+=ca[nColCount-1];

tempsql+=")";

for(int itemnum=0;itemnum

sSql ="INSERT INTO Sheet1 ";

sSql+=tempsql;

sSql+="VALUES ('";

for(i =0 ; i< nColCount-1; i++)

{

sSql+=resultlist.GetItemText(itemnum, i);

sSql+="','";

}

sSql+=resultlist.GetItemText(itemnum, nColCount-1); sSql+="')";

database.ExecuteSQL(sSql);

}

}

// 关闭数据库

VFP中的列表框控件(listbox)

VFP中的列表框控件(listbox) 一.列表框(listbox):主要用于选择一组指定的数据,用户从列表中选取选项,然后执行所需的操作. 二.列表框常用属性:见下表 注1(rowsourcetype属性可指定的值): 0-无,运行时使用列表框的确良additem和addlistitem方法加入 1-值,将列表框的内容在设计时直接写在该属性中 2-表别名:由columncount确定表中选择的字段.当用户选择列表框时,记录指针将自动移到该记录上 3-sql语句:见sql部分,由执行的结果产生. 4-查询文件名:见查询部分,由查询结果产生 5-数组名 6-字段名表:可用表别名作为字段前缀.当用户选择列表项时,记录指针将自动移到该记录上7-文件名描述框架,可包含"*"和"?"来描述在列表框中显示的文件名 8-结构

9-弹出式菜单,提供向后兼容. 二.列表框常用的方法:见下表 三.列表框常用事件:列表框的常用事件为click(单击)事件和dbclick(双击)事件. 四.例:列表框练习 1.新建表单,添加一个文本框text1,三个命令按钮command1~command3,三个命令按钮的caption属性依次设为"加入","移出"和"全部移出",一个列表框list1.界面如图25 2.设置属性:将表单的caption属性设为"列表框练习",autocenter属性设为.T.;将列表框list1的moverbars属性设为.T.,multiselect属性设为.T. 3.编写代码: ●"加入"命令按钮command1的click事件: qm=thisform.text1.value IF !empty(qm) no=.t. FOR i=1 to thisform.list1.listcount IF thisform.list1.list(i)=qm &&如果文本框中输入的内容和列表框中已存在的内容相同,则不添加 no=.f. ENDIF NEXT i IF no thisform.list1.additem(qm) thisform.refresh

关于WPF的listbox控件绑定问题

关于WPF的listbox控件 首先关于listbox以及datagrid 人们比较喜欢用datagrid来绑定数据,应为它的文本生成出来比listbox要整齐,相对来说listbox生成的文本可以用四个字来形容----不堪入目!下面我用2个控件做出的效果: 发现没?Listbox也能使之对齐。。详解如下: 前台绑定:XAML 其中Name;Gends;Age;Hobby 分别为实例类的属性(也是表的属性); 再看后台很简洁;

C++ #pragma code_seg用法

#pragma code_seg 格式如: #pragma code_seg( [ [ { push | pop}, ] [ identifier, ] ] [ "segment-name" [, "segment-class" ] ) 该指令用来指定函数在.obj文件中存放的节,观察OBJ文件可以使用VC自带的dumpbin命令行程序,函数在.obj文件中默认的存放节为.text节,如果code_seg 没有带参数的话,则函数存放在.text节中。 push (可选参数)将一个记录放到内部编译器的堆栈中,可选参数可以为一个标识符或者节名 pop(可选参数)将一个记录从堆栈顶端弹出,该记录可以为一个标识符或者节名identifier(可选参数)当使用push指令时,为压入堆栈的记录指派的一个标识符,当该标识符被删除的时候和其相关的堆栈中的记录将被弹出堆栈 "segment-name" (可选参数)表示函数存放的节名 例如: //默认情况下,函数被存放在.text节中 void func1() {// stored in .text } //将函数存放在.my_data1节中 #pragma code_seg(".my_data1") void func2() {// stored in my_data1 } //r1为标识符,将函数放入.my_data2节中 #pragma code_seg(push, r1, ".my_data2") void func3() {// stored in my_data2 } int main() { } 例如 #pragma code_seg(“PAGE”) 作用是将此部分代码放入分页内存中运行。 #pragma code_seg() 将代码段设置为默认的代码段 #pragma code_seg("INIT") 加载到INIT内存区域中,成功加载后,可以退出内存

ListBox控件

ListBox控件 1.功能 ListBox控件显示较长的选项列表,用户可从中选择一项或多项。如果项总数超出可以显示的项数,则自动向ListBox控件添加滚动条。ListBox控件列表中的每个元素称为项。图1所示为ListBox控件。 图1 ListBox控件 2.属性 ListBox控件常用属性及说明如表1所示。 表1 ListBox控件常用属性及说明 下面对比较重要的属性进行详细介绍。 (1)Items属性。该属性用于查看列表框中的项。 语法: public ObjectCollection Items { get; } 属性值:ListBox.ObjectCollection表示ListBox中的项。 说明: ① 该属性使用户可以获取对当前存储在 ListBox 中的项列表的引用。通过此引用,可以在集合中添加项、移除项和获得项的计数。

② 可以使用DataSource属性来操控ListBox的项。如果使用DataSource属性向ListBox 添加项,则可以使用Items属性查看ListBox中的项,但不能使用 ListBox.ObjectCollection的方法向该列表添加项或从中移除项。 (2)SelectedItem属性。该属性表示当前选中的项。 语法: public Object SelectedItem { get; set; } 属性值:表示控件中当前选定内容的对象。 说明:对于标准 ListBox,可以使用此属性确定在ListBox中选定了哪个项。如果 ListBox 的SelectionMode属性设置为SelectionMode.MultiSimple或 SelectionMode.MultiExtended(它指示多重选择ListBox),并在该列表中选定了多个项,则此属性可返回任何选定的项。 示例 把左边的文本框中的内容移到右边的文本框中 本示例主要使用Items属性向ListBox1控件添加项,然后使用SelectedItem属性将ListBox1控件中的选中项添加到ListBox2控件中。示例运行结果如图2和图3所示。 图2 ListBox1中项移动前 图3 ListBox1中项移动后 程序主要代码如下: SqlConnection con = new SqlConnection("server=ZHY\\zhy;uid=sa;pwd=;database=student"); con.Open(); SqlCommand com = new SqlCommand("select * from student",con); SqlDataReader dr = com.ExecuteReader();

C++ #pragma预处理命令

#pragma预处理命令 #pragma可以说是C++中最复杂的预处理指令了,下面是最常用的几个#pragma 指令: #pragma comment(lib,"XXX.lib") 表示链接XXX.lib这个库,和在工程设置里写上XXX.lib的效果一样。 #pragma comment(linker,"/ENTRY:main_function") 表示指定链接器选项/ENTRY:main_function #pragma once 表示这个文件只被包含一次 #pragma warning(disable:4705) 表示屏蔽警告4705 C和C++程序的每次执行都支持其所在的主机或操作系统所具有的一些独特的特点。例如,有些程序需要精确控制数据存放的内存区域或控制某个函数接收的参数。#pragma为编译器提供了一种在不同机器和操作系统上编译以保持C和C++完全兼容的方法。#pragma是由机器和相关的操作系统定义的,通常对每个编译器来说是不同的。 如果编译器遇到不认识的pragma指令,将给出警告信息,然后继续编译。Microsoft C and C++ 的编译器可识别以下指令:alloc_text,auto_inline,bss_seg,check_stack,code_seg,comment,component,conform,const_seg,data_seg,deprecated,fenv_access,float_control,fp_contract,function,hdrstop,include_alias,init_seg,inline_depth,inline_recursion,intrinsic,make_public,managed,message,omp,once,optimize,pack,pointers_to_members,pop_macro,push_macro,region, endregion,runtime_checks,section,setlocale,strict_gs_check,unmanaged,vtordisp,warning。其中conform,init_seg, pointers_to_members,vtordisp仅被C++编译器支持。 以下是常用的pragma指令的详细解释。 1.#pragma once。保证所在文件只会被包含一次,它是基于磁盘文件的,而#ifndef 则是基于宏的。

VB中ListBox的应用

https://www.doczj.com/doc/7215806662.html,入门——ListBox控件的使用 【字体大小:小中大】2008-02-18 19:56 来源:作者: ListBox(列表框)控件可以显示一组项目的列表,用户可以根据需要从中选择一个或多个选项。列表框可以为用户提供所有选项的列表。虽然也可设置列表框为多列列表的形式,但在缺省时列表框单列垂直显示所有的选项,如果项目数目超过了列表框可显示的数目,控件上将自动出现滚动条。这时用户可在列表中上、下、左、右滚动。ListBox控件在工具箱中的图标如图所示: 一、ListBox常用属性 1、BackColor 属性:用于显示ListBox控件中的文本和图形的背景颜色,默认为白色(Window) 2、BorderStyle 属性:控制在列表框ListBox周围绘制的边框的类型,其枚举值为下面三个: BorderStyle.None——无边框 BorderStyle.FixedSingle——单行边框 BorderStyle.Fixed3D——三维边框 默认值为BorderStyle.Fixed3D。 3、Font、ForeColor 属性:前者用于调整列表框中文本的字体,后者用于调整文本框中文本或者图形的前景色。 4、MultiColumn 属性:指示列表框中的项是否以水平的方式在列表框中显示,默认为False,此时所有的项都只显示为一列,当列表框无法显示全部的项的时候,将会出现一个垂直的滚动条;如果MultiColumn属性为True,则列表框以多列的形式来显示所有的项,如果一列无法全部显示完,则在水平位置重新显示一列,直到显示完毕为止,此时将会出现一个水平滚动条,如下图一所示:

#pragma data code ICCAVR的使用

#pragma data:code 在Keil中为了节省数据存储器的空间,通过“code”关键字来定义一个数组或字符串将被存储在程序存储器中: uchar code buffer[]={0,1,2,3,4,5}; uchar code string[]="Armoric" ; 而这类代码移值到ICCAVR上时是不能编译通过的。我们可以通过"const" 限定词来实现对存储器的分配: #pragma data:code const unsigned char buffer[]={0,1,2,3,4,5}; const unsigned char string[]="Armoric"; #pragma data:data 注意: 《1》使用ICCAVR6.31时,#pragma data :code ;#pragma data:data ; 这些语法时在"data:cod"、"data:data"字符串中间不能加空格,否则编译不能通过。 《2》const 在ICCAVR是一个扩展关键词,它与ANSIC标准有冲突,移值到其它的编译器使用时也需要修改相关的地方。 在ICCAVR中对数组和字符串的五种不同空间分配: const unsigned char buffer[]={0,1,2,3,4,5}; //buffer数组被分配在程序存储区中 const unsigned char string[]="Armoric" ; //stringp字符串被分配在程序存储区中 const unsigned char *pt //指针变量pt被分配在数据存储区中,指向程序存储区中的字符类型数据 unsigned char *const pt //指针变量pt被分配在程序存储区中,指向数据存储区中的字符类型数据 const unsigned char *const pt //指针变量pt被分配在程序存储区,指向程序存储区中的字符类型数据 unsigned char *pt //指针变量pt被分配在数据存储区中,指向数据存储区中的数据 请问#pragma data:code和#pragma data:data是什么意思? 前者表示:随后的数据将存贮在程序区,即FLASH区,此区只能存贮常量,比如表格之类。

pragma的用法

#pragma的用法 在所有的预处理指令中,#Pragma 指令可能是最复杂的了,它的作用是设定编译器的状态或者是指示编译器完成一些特定的动作。#pragma指令对每个编译器给出了一个方法,在保持与C和C++语言完全兼容的情况下,给出主机或操作系统专有的特征。依据定义, 编译指示是机器或操作系统专有的,且对于每个编译器都是不同的。 其格式一般为: #pragma para。其中para为参数,下面来看一些常用的参数。 1)message 参数 message参数是我最喜欢的一个参数,它能够在编译信息输出窗口中输出相应的信息,这对于源代码信息的控制是非常重要的。其使用方法为: #pragma message("消息文本") 当编译器遇到这条指令时就在编译输出窗口中将消息文本打印出来。 当我们在程序中定义了许多宏来控制源代码版本的时候,我们自己有可能都会忘记有 没有正确的设置这些宏, 此时我们可以用这条指令在编译的时候就进行检查。假设我们希望判断自己有没有在源代码的什么地方定义了_X86这个宏, 可以用下面的方法: #ifdef _X86 #pragma message("_X86 macro activated!") #endif 我们定义了_X86这个宏以后,应用程序在编译时就会在编译输出窗口里显示"_86 macro activated!"。 我们就不会因为不记得自己定义的一些特定的宏而抓耳挠腮了。 (2)另一个使用得比较多的pragma参数是code_seg 格式如: #pragma code_seg( ["section-name" [, "section-class"] ] ) 它能够设置程序中函数代码存放的代码段,当我们开发驱动程序的时候就会使用到 它。 (3)#pragma once (比较常用) 只要在头文件的最开始加入这条指令就能够保证头文件被编译一次,这条指令实际上 在VC6中就已经有了, 但是考虑到兼容性并没有太多的使用它。 (4)#pragma hdrstop 表示预编译头文件到此为止,后面的头文件不进行预编译。BCB可以预编译头文件以 加快链接的速度, 但如果所有头文件都进行预编译又可能占太多磁盘空间,所以使用这个选项排除一些头文

DropDownList,ListBox控件

5.7 列表控件(DropDownList,ListBox) 在Web开发中,经常会需要使用列表控件,让用户的输入更加简单。例如在用户注册时,用户的所在地是有限的集合,而且用户不喜欢经常键入,这样就可以使用列表控件。同样列表控件还能够简化用户输入并且防止用户输入在实际中不存在的数据,如性别的选择等。 5.7.1 DropDownList列表控件 列表控件能在一个控件中为用户提供多个选项,同时又能够避免用户输入错误的选项。例如,在用121 户注册时,可以选择性别是男,或者女,就可以使用DropDownList列表控件,同时又避免了用户输入其他的信息。因为性别除了男就是女,输入其他的信息说明这个信息是错误或者是无效的。下列语句声明了一个DropDownList列表控件,示例代码如下所示。 1 2 3 4 5 6 7 上述代码创建了一个DropDownList列表控件,并手动增加了列表项。同时DropDownList列表控件也可以绑定数据源控件。DropDownList列表控件最常用的事件是SelectedIndexChanged,当DropDownList列表控件选择项发生变化时,则会触发该事件,示例代码如下所示。 protected void DropDownList1_SelectedIndexChanged1(object sender, EventArgs e) { Label1.Text = "你选择了第" + DropDownList1.Text + "项"; } 上述代码中,当选择的项目发生变化时则会触发该事件,如图5-14所示。当用户再次进行选择时,系统会将更改标签1中的文本,如图5-15所示。 当用户选择相应的项目时,就会触发SelectedIndexChanged事件,开发人员可以通过捕捉相应的用户选中的控件进行编程处理,这里就捕捉了用户选择的数字进行字体大小的更改。 5.7.2 ListBox列表控件

stm32中使用#pragma pack(非常有用的字节对齐用法说明)

#pragma pack(4) //按4字节对齐,但实际上由于结构体中单个成员的最大占用字节数为2字节,因此实际还是按2字节对齐 typedef struct { char buf[3];//buf[1]按1字节对齐,buf[2]按1字节对齐,由于buf[3]的下一成员word a是按两字节对齐,因此buf[3]按1字节对齐后,后面只需补一空字节 word a; //#pragma pack(4),取小值为2,按2字节对齐。 }kk; #pragma pack() //取消自定义字节对齐方式 对齐的原则是min(sizeof(word ),4)=2,因此是2字节对齐,而不是我们认为的4字节对齐。 这里有三点很重要: 1.每个成员分别按自己的方式对齐,并能最小化长度 2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度 3.对齐后的结构体整体长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐 补充一下,对于数组,比如: char a[3];这种,它的对齐方式和分别写3个char是一样的.也就是说它还是按1个字节对齐. 如果写: typedef char Array3[3]; Array3这种类型的对齐方式还是按1个字节对齐,而不是按它的长度. 不论类型是什么,对齐的边界一定是1,2,4,8,16,32,64....中的一个. 声明: 整理自网络达人们的帖子,部分参照MSDN。 作用: 指定结构体、联合以及类成员的packing alignment; 语法: #pragma pack( [show] | [push | pop] [, identifier], n ) 说明: 1,pack提供数据声明级别的控制,对定义不起作用; 2,调用pack时不指定参数,n将被设成默认值; 3,一旦改变数据类型的alignment,直接效果就是占用memory的减少,但是performance会下降; 语法具体分析: 1,show:可选参数;显示当前packing aligment的字节数,以warning message的形式被显示; 2,push:可选参数;将当前指定的packing alignment数值进行压栈操作,这里的栈是the internal compiler stack,同时设置当前的packing alignment为n;如果n没有指定,则将当前的packing alignment数值压栈; 3,pop:可选参数;从internal compiler stack中删除最顶端的record;如果没有指定n,则当前栈顶record即为新的packing alignment 数值;如果指定了n,则n将成为新的packing aligment数值;如果指定了identifier,则internal compiler stack中的record都将被pop 直到identifier被找到,然后pop出identitier,同时设置packing alignment数值为当前栈顶的record;如果指定的identifier并不存在于internal compiler stack,则pop操作被忽略; 4,identifier:可选参数;当同push一起使用时,赋予当前被压入栈中的record一个名称;当同pop一起使用时,从internal compiler stack 中pop出所有的record直到identifier被pop出,如果identifier没有被找到,则忽略pop操作; 5,n:可选参数;指定packing的数值,以字节为单位;缺省数值是8,合法的数值分别是1、2、4、8、16。 重要规则: 1,复杂类型中各个成员按照它们被声明的顺序在内存中顺序存储,第一个成员的地址和整个类型的地址相同; 2,每个成员分别对齐,即每个成员按自己的方式对齐,并最小化长度;规则就是每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数中较小的一个对齐; 3,结构体、联合体或者类的数据成员,第一个放在偏移为0的地方;以后每个数据成员的对齐,按照#pragma pack指定的数值和这个数据成员自身长度两个中比较小的那个进行;也就是说,当#pragma pack指定的值等于或者超过所有数据成员长度的时候,这个指定值的大小将不产生任何效果; 4,复杂类型(如结构体)整体的对齐是按照结构体中长度最大的数据成员和#pragma pack指定值之间较小的那个值进行;这样当数据成员为复杂类型(如结构体)时,可以最小化长度; 5,复杂类型(如结构体)整体长度的计算必须取所用过的所有对齐参数的整数倍,不够补空字节;也就是取所用过的所有对齐参数中最大的那个值的整数倍,因为对齐参数都是2的n次方;这样在处理数组时可以保证每一项都边界对齐; 对齐的算法:由于各个平台和编译器的不同,现以本人使用的gcc version 3.2.2编译器(32位x86平台)为例子,来讨论编译器对struct 数据结构中的各成员如何进行对齐的。 在相同的对齐方式下,结构体内部数据定义的顺序不同,结构体整体占据内存空间也不同,如下: 设结构体如下定义: struct A { int a; //a的自身对齐值为4,偏移地址为0x00~0x03,a的起始地址0x00满足0x00%4=0;

#pragma指令用法汇总和解析

#pragma指令用法汇总和解析 一. message 参数。 message 它能够在编译信息输出窗 口中输出相应的信息,这对于源代码信息的控制是非常重要的。其使用方法为: #pragma message(“消息文本”) 当编译器遇到这条指令时就在编译输出窗口中将消息文本打印出来。 当我们在程序中定义了许多宏来控制源代码版本的时候,我们自己有可能都会忘记有没有正确的设置这些宏,此时我们可以用这条 指令在编译的时候就进行检查。假设我们希望判断自己有没有在源代码的什么地方定义了_X86这个宏可以用下面的方法 #ifdef _X86 #pragma message(“_X86 macro activated!”) #endif 当我们定义了_X86这个宏以后,应用程序在编译时就会在编译输出窗口里显示“_ X86 macro activated!”。我们就不会因为不记得自己定义的一些特定的宏而抓耳挠腮了 二. 另一个使用得比较多的#pragma参数是code_seg。格式如: #pragma code_seg( [ [ { push | pop}, ] [ identifier, ] ] [ "segment-name" [, "segment-class" ] ) 该指令用来指定函数在.obj文件中存放的节,观察OBJ文件可以使用VC自带的dumpbin命令行程序,函数在.obj文件中默认的存放节 为.text节 如果code_seg没有带参数的话,则函数存放在.text节中 push (可选参数) 将一个记录放到内部编译器的堆栈中,可选参数可以为一个标识符或者节名 pop(可选参数) 将一个记录从堆栈顶端弹出,该记录可以为一个标识符或者节名 identifier (可选参数) 当使用push指令时,为压入堆栈的记录指派的一个标识符,当该标识符被删除的时候和其相关的堆栈中的记录将被弹出堆栈 "segment-name" (可选参数) 表示函数存放的节名 例如: //默认情况下,函数被存放在.text节中 void func1() { // stored in .text } //将函数存放在.my_data1节中 #pragma code_seg(".my_data1") void func2() { // stored in my_data1 } //r1为标识符,将函数放入.my_data2节中 #pragma code_seg(push, r1, ".my_data2") void func3() { // stored in my_data2 } int main() { } 三. #pragma once (比较常用) 这是一个比较常用的指令,只要在头文件的最开始加入这条指令就能够保证头文件被编译一次 四. #pragma hdrstop表示预编译头文件到此为止,后面的头文件不进行预编译。

https://www.doczj.com/doc/7215806662.html,入门分组控件:checkedlistbox控件的使用

https://www.doczj.com/doc/7215806662.html,入门——分组控件:CheckedListBox控件的使用https://www.doczj.com/doc/7215806662.html,入门——分组控件:CheckedListBox控件的使用 在https://www.doczj.com/doc/7215806662.html,中,CheckBox、CheckedListBox、RadioButton 和TrackBar这四个控件的功能都是设置和获取值的,我们 称之为设置值的控件。 前面我们了解了CheckBox控件和RadioButton控件的使用,这里我们来看CheckedListBox控件的使用,CheckedListBox控件在工具箱中的图标如图所示: Windows窗体的CheckedListBox控件,扩展了ListBox控件(https://www.doczj.com/doc/7215806662.html,入门——ListBox控件的使用)。它几乎可以完成列表框控件(ListBox)可以完成的所有任务,并且还可以在列表中的项旁边显示复选的标记。这两种控件的其他差异是:CheckedListBox控件(也称复选列表框)只支持DrawMode.Normal,并且复选列表框只能有一项选定或者没有任何选定,选定的项在窗体上突出显示,与以选中的项区别。 一、常用属性和方法 CheckedListBox控件的属性和方法基本上都可以在ListBox

控件中找到,可以参看这里:https://www.doczj.com/doc/7215806662.html,入门——ListBox控件的使用。值得我们重视的是,CheckedListBox控件的CheckedItems属性,它是CheckedListBox控件中复选框选中的项的集合,我们可以通过检索该属性来获得选中的项。CheckOnClick 指示是否只要一选择项即切换复选框。默认行为是在首次单击时更改选定内容,然后让用户再次单击以应用选中标记。但在某些情况下,您可能愿意一单击项就选中它。 下面我们就直接以实例来了解和掌握CheckedListBox控件的方法和属性。 二、在CheckedListBox控件中添加、移除项 因为CheckedListBox控件控件的使用和ListBox控件相似,所以我们这里就只针对用编程的方法来对CheckedListBox 控件的操作。 1、添加项 添加一个名为“新建文件”的项,且复选框为选中状态 CheckedListBox1.Items.Add("新建文件", True) 添加一个名为“拷贝文件”的项,且复选框为未选中状态 CheckedListBox1.Items.Add("拷贝文件", False) 2、删除项

向量化的方法

使用英特尔编译器进行自动向量化 作者:Yang Wang (Intel) 自动向量化是英特尔编译器提供的一个可以自动的使用SIMD指示的功能。在处理数据时,编译器自动选择MMX?, Intel? Streaming SIMD 扩展(Intel? SSE, SSE2, SSE3 和SSE4)等指令集,对数据进行并行的处理。使用编译器提供的自动向量化功能是提高程序性能的一个非常有效的手段。自动向量化在IA-32和Intel? 64的平台上均提供很好的支持。 英特尔编译器提供的自动向量化相关的编译选项如下所示。”/Q”开头的选项是针对Windows平台的,“-“开头的选项是针对Linux*和Mac平台的。 -x, /Qx 按照该选项指定的处理器类型生成相应的优化代码。比如-xSSE3, 该选项指定编译器生成Intel? SSE3指令的代码。又比如-xSSE3_ATOM, 该选项针对Intel? Atom? 处理器进行优化。 -ax, /Qax 如果指定该选项,在生成的单一目标文件中,不但会生成专门针对指定的处理器类型进行优化的代码,同时也生成通用的IA-32架构的代码。该选项主要是为了生成代码的兼容性考虑。 -vec, /Qvec 打开或者关闭编译器的向量化优化。默认情况下自动向量化是打开的。 -vec-report, /Qvec-report 该选项用户控制在编译过程中产生的向量化消息报告。 编译器提供的自动向量化优化默认情况下是打开的。在编译过程中我们可以使用-vec-report选项来打开向量化诊断消息报告。这样编译器可以告诉我们有哪些循环被向量化了,有哪些循环没有被向量化已经无法向量化的原因。 在编译程序的过程中,有时候我们会发现编译器报告说某个循环无法被向量化。很多时候无法向量化的原因都是因为循环中存在的变量依赖关系。有时候我们可以修改程序来消除这种依赖关系,有的时候我们可以使用编译器提供的一些编译指示来显示的告诉编译器如何处理这种依赖关系。即使在某个循环已经可以被自动向量化的时候,使用编译器提供的对向量化的语言支持和编译指示还可以提高编译器向量化的效率,提高程序执行的性能。 下面我们来详细解释一下编译器提供的编译指示以及这些指示对编译器编译的影响。 在Intel编译器中,我们提供下面这样一些对自动向量化的语言支持和编译指示。 __declspec(align(n)) 指导编译器将变量按照n字节对齐 __declspec(align(n,off)) 指导编译器将变量按照n字节再加上off字节的编译量进行对齐 restrict 消除别名分析中的二义性 __assume_aligned(a,n) 当编译器无法获取对齐信息时,假定数组a已经按照n字节对齐 #pragma ivdep 提示编译器忽略可能存在的向量依赖关系 #pragma vector {aligned|unaligned|always}

MFC ListBox控件用法介绍

列表控件可以看作是功能增强的ListBox,它提供了四种风格,而且可以同时显示一列的多中属性值。MFC中使用CListCtrl类来封装列表控件的各种操作。通过调用?BOOLCreate(DWORDdwStyle,constRECT&rect,CWnd*pParentWnd,UINTnID);创建一个窗口,dwStyle中可以使用以下一些列表控件的专用风格: ?LVS_ICONLVS_SMALLICONLVS_LISTLVS_REPORT这四种风格决定控件的外观,同时只可以选择其中一种,分别对应:大图标显示,小图标显示,列表显示,详细报表显示 ?LVS_EDITLABELS结点的显示字符可以被编辑,对于报表风格来讲可编辑的只为第一列。 ?LVS_SHOWSELALWAYS在失去焦点时也显示当前选中的结点 ?LVS_SINGLESEL同时只能选中列表中一项 首先你需要设置列表控件所使用的ImageList,如果你使用大图标显示风格,你就需要以如下形式调用:? CImageList*SetImageList(CImageList*pImageList,LVSIL_NORMAL);? 如果使用其它三种风格显示而不想显示图标你可以不进行任何设置,否则需要以如下形式调用:? CImageList*SetImageList(CImageList*pImageList,LVSIL_SMALL); 通过调用intInsertItem(intnItem,LPCTSTRlpszItem);可以在列表控件中nItem指明位置插入一项,lpszItem为显示字符。除LVS_REPORT风格外其他三种风格都只需

OpenMP的用法

在双重循环中怎样写OpenMP? 那要分析你的外循环跟内循环有没有彼此依赖的关系 unsigned int nCore = GetComputeCore(); unsigned int nStep = IMAGETILEYSIZE / nCore; #pragma omp parallel for private(Level0_x, Level0_y, ChangeLevel0_x, ChangeLevel0_y, InterX1, InterX2, InterY1, InterY2) for (int k = 0; k < nCore; k++) { int begin = k * nStep; int end = (k + 1) * nStep; for (int YOff = begin; YOff < end; YOff++) { for (int XOff = 0; XOff < IMAGETILEXSIZE; XOff++) { Level0_x = pPixelXBuf[YOff][XOff]; Level0_y = pPixelYBuf[YOff][XOff]; ChangeLevel0_x = Level0_x - XMin; ChangeLevel0_y = Level0_y - YMin; //寻找坐标在Level1Buf中对应的4个像素值 InterX1 = (int)(ChangeLevel0_x); InterX2 = (int)(ChangeLevel0_x + 1); InterY1 = (int)(ChangeLevel0_y); InterY2 = (int)(ChangeLevel0_y + 1); //双线性插值对Level0_Buf赋值 ZoomInterpolation(Level0Buf, Level1Buf, ChangeLevel0_x, ChangeLevel0_y, SamplesPerPixel, nXSize, nYSize, InterX1, InterX2, InterY1, InterY2, XOff, YOff); } } } 我也想应该这样,可是如果nCore=1的时候,外循环只循环一次,线程是怎么分配的呢。其实最外层的循环如果很多,就在外循环分配线程是不是就可以不考虑里面的循环了? nCore = 1,就是单核单cpu,多核循环就跟普通的循环没有差别, openmp默认有几个内核就开几个线程同时运行。所以单核openmp也没有什么意义,此时你也可以开两个线程“同时”运行,但在单核机器上,两个线程是不可能同时运行的 可以不考虑里面的循环。你只要保证外循环跟外循环之间,内寻环跟内循环之间没有数据依赖关系就行。 假设 for (int i = 0; i < 200000000; i++)

CSharp对ListBox重写

WinForms中重写ListBox控件 /* **使用时 simListBox1.ItemCollection.Add(1, "百里屠苏"); simListBox1.ItemCollection.Add(2, "风晴雪"); simListBox1.ItemCollection.Add(3, "方兰生"); simListBox1.ItemCollection.Add(4, "欧阳少恭"); simListBox1.ItemCollection.Add(5, "工长君"); simListBox1.ItemCollection.Add(6, "古剑奇谭"); simListBox1.SelectionMode = SelectionMode.MultiExtended;//默认值是:只能选择一项在按钮的单击事件中: private void button1_Click(object sender, EventArgs e) { for (int i = 0; i < simListBox1.SelectedListBoxItems.Count; i++) { //查看选择的所有项的显示内容 MessageBox.Show(simListBox1.SelectedListBoxItems[i].Key.ToString()); MessageBox.Show(simListBox1.SelectedListBoxItems[i].Item.ToString()); } } */ SimListBox控件源代码如下: using System; using System.Collections.Generic; using https://www.doczj.com/doc/7215806662.html,ponentModel; using System.Drawing; using System.Data; using System.Text; using System.Windows.Forms; namespace DoorControl { ///

/// 专门用于填充ListBox信息方法 /// public partial class SimListBox : ListBox { //AutoScaleMode AutoScaleMode;请在SimListBox.designer.cs中注释掉 //this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; public SimListBox()

sizeof用法总结

sizeof用法总结 本文主要包括二个部分,第一部分重点介绍在VC中,怎么样采用sizeof来求结构的大小,以及容易出现的问题,并给出解决问题的方法,第二部分总结出VC中sizeof的主要用法。 1、sizeof应用在结构上的情况 请看下面的结构: struct MyStruct { double dda1; char dda; int type }; 对结构MyStruct采用sizeof会出现什么结果呢?sizeof(MyStruct)为多少呢?也许你会这样求: sizeof(MyStruct)=sizeof(double)+sizeof(char)+sizeof(int)=13 但是当在VC中测试上面结构的大小时,你会发现sizeof(MyStruct)为16。你知道为什么在VC中会得出这样一个结果吗? 其实,这是VC对变量存储的一个特殊处理。为了提高CPU的存储速度,VC对一些变量的起始地址做了“对齐”处理。在默认情况下,VC规定各成员变量存放的起始地址相对于结构的起始地址的偏移量必须为该变量的类型所占用的字节数的倍数。下面列出常用类型的对齐方式(vc6.0,32位系统)。 类型 对齐方式(变量存放的起始地址相对于结构的起始地址的偏移量) Char 偏移量必须为sizeof(char)即1的倍数 int 偏移量必须为sizeof(int)即4的倍数 float 偏移量必须为sizeof(float)即4的倍数 double 偏移量必须为sizeof(double)即8的倍数

Short 偏移量必须为sizeof(short)即2的倍数 各成员变量在存放的时候根据在结构中出现的顺序依次申请空间,同时按照上面的对齐方式调整位置,空缺的字节VC会自动填充。同时VC为了确保结构的大小为结构的字节边界数(即该结构中占用最大空间的类型所占用的字节数)的倍数,所以在为最后一个成员变量申请空间后,还会根据需要自动填充空缺的字节。 下面用前面的例子来说明VC到底怎么样来存放结构的。 struct MyStruct { double dda1; char dda; int type }; 为上面的结构分配空间的时候,VC根据成员变量出现的顺序和对齐方式,先为第一个成员dda1分配空间,其起始地址跟结构的起始地址相同(刚好偏移量0刚好为sizeof(double)的倍数),该成员变量占用sizeof(double)=8个字节;接下来为第二个成员dda分配空间,这时下一个可以分配的地址对于结构的起始地址的偏移量为8,是sizeof(char)的倍数,所以把dda存放在偏移量为8的地方满足对齐方式,该成员变量占用sizeof(char)=1个字节;接下来为第三个成员type分配空间,这时下一个可以分配的地址对于结构的起始地址的偏移量为9,不是sizeof(int)=4的倍数,为了满足对齐方式对偏移量的约束问题,VC自动填充3个字节(这三个字节没有放什么东西),这时下一个可以分配的地址对于结构的起始地址的偏移量为12,刚好是sizeof(int)=4的倍数,所以把type存放在偏移量为12的地方,该成员变量占用sizeof(int)=4个字节;这时整个结构的成员变量已经都分配了空间,总的占用的空间大小为:8+1+3+4=16,刚好为结构的字节边界数(即结构中占用最大空间的类型所占用的字节数sizeof(double)=8)的倍数,所以没有空缺的字节需要填充。所以整个结构的大小为: sizeof(MyStruct)=8+1+3+4=16,其中有3个字节是VC自动填充的,没有放任何有意义的东西。 下面再举个例子,交换一下上面的MyStruct的成员变量的位置,使它变成下面的情况: struct MyStruct { char dda; double dda1;

相关主题
文本预览
相关文档 最新文档