=============================================
11.8
做项目合成函数块时,在未完成全部功能时,可先在一函数内完全实现,之后在把函数内重复的代码分到其他函数,这样就减少数据不一至现象.
==================================================
11.12
memcmp(lptemp2,c2,mSize);比较内存中字符
最好进行进制转换时不返回CString,而直接修改char类型的内存.
==================================================
11.21
QueryPerformanceFrequence 得到系统计数器频率
QueryPerformanceCounter 得到系统计数器当前数值
搭配使用可精确计时(ms)
BeginWaitCursor();
LARGE_INTEGER Freg;
QueryPerformanceFrequency(&Freg);
AfxMessageBox("开始");
LARGE_INTEGER lpPerformanceCount;
LARGE_INTEGER lpPerformanceCount2;
QueryPerformanceCounter(&lpPerformanceCount);
AfxMessageBox("停止");
QueryPerformanceCounter(&lpPerformanceCount2);
m_process.SetPos(99);
long Fregpc=(long)Freg.QuadPart;
str.Format("%ld",Fregpc);
AfxMessageBox("频率是"+str);
long i=(long)((lpPerformanceCount2.QuadPart-lpPerformanceCount.QuadPart)/Freg.QuadPart);
str.Format("%ld",i);
AfxMessageBox(str);
void BeginWaitCursor( );
Remarks
Call this function to display the cursor as an hourglass when you expect a command to take a noticeable time interval to execute. The framework calls this function to show the user that it is busy, such as when a CDocument object loads or saves itself to a file.
CString型的变量在调用GetBuffer方法后,要调用ReleaseBuffer方法,才能正常使用该变量.
===============================================
11.22
GetPrivateProfileInt
The GetPrivateProfileInt function retrieves an integer associated with a key in the specified section of the given initialization file. This function is provided for compatibility with 16-bit Windows-based applications. Win32-based applications should store initialization information in the registry.
UINT GetPrivateProfileInt(
LPCTSTR lpAppName, // address of section name
LPCTSTR lpKeyName, // address of key name
INT nDefault, // return value if key name is not found
LPCTSTR lpFileName // address of initialization filename
);
Parameters
- lpAppName
- Pointer to a null-terminated string containing the section name in the initialization file.
- lpKeyName
- Pointer to the null-terminated string containing the key name whose value is to be retrieved. This value is in the form of a string; the GetPrivateProfileInt function converts the string into an integer and returns the integer.
- nDefault
- Specifies the default value to return if the key name cannot be found in the initialization file.
- lpFileName
- Pointer to a null-terminated string that names the initialization file. If this parameter does not contain a full path to the file, the system searches for the file in the Windows directory.
- 注意第三个参数nDefault,在没有找到相同的value则返回该值
CMenu menu;
menu.LoadMenu(IDR_MENU1);
SetMenu(&menu);
menu.Detach();
LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES
LVS_EX_FULLROWSELECT 整行高亮
LVS_EX_GRIDLINES 格子
=================================
11.23
CMenu menu;
DWORD dwSelect;
menu.LoadMenu(IDR_TRMMENU);
CMenu *pmenuPopup = menu.GetSubMenu(0);最上面的一行ITEM
if(usc==1)
pmenuPopup->EnableMenuItem (IDM_MODIFYUSER,MF_ENABLED);下面的细的ITEM
else
pmenuPopup->EnableMenuItem (IDM_MODIFYUSER,MF_GRAYED);
POINT point;
POINT point;
GetCursorPos(&point); //保存位置
DWORD dwFlags=TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_NONOTIFY|TPM_RETURNCMD;
dwSelect=pmenuPopup->TrackPopupMenu(dwFlags,point.x, point.y, this);
pmenuPopup->DestroyMenu();
Displays a floating pop-up menu at the specified location and tracks the selection of items on the pop-up menu. A floating pop-up menu can appear anywhere on the screen.
显示一个浮动的MENU,并获得选择的ITEM.
关于全局变量
新添加lib.cpp,lib.h
里面定义
int i=100;
则另一个类用extern int i;
可使用,不必要用到#include "lib.h"
还有
如果lib.h定义了int i;
而lib2.h引入了lib.h
最后工程cpp引入了lib.h
则工程cpp可以用lib.h里面定义的变量
=====================================
11.25
背景
CBitmap cbmp;
if(hImage_background==NULL)
{
hImage_background = (HBITMAP)LoadImage(AfxGetApp()->m_hInstance,
"C:\\vc++\\test\\ChinaCDC.bmp",
IMAGE_BITMAP,
0, 0,
LR_CREATEDIBSECTION|LR_DEFAULTSIZE|LR_LOADFROMFILE);
}
cbmp.Attach(hImage_background);
CBrush bsh(&cbmp);
CPaintDC dc(this);
CRect rc;
GetClientRect(&rc);
dc.FillRect(&rc,&bsh);
cbmp.Detach();
PostMessage(WM_SYSCOMMAND,SC_MAXIMIZE,0);//程序框放最大
至于系统拦菜单可以工程设置或者代码
CMenu menu;
menu.LoadMenu(IDR_MAINFRAME);
AfxGetMainWnd()->SetMenu(&menu);
AfxGetMainWnd()->DrawMenuBar();
menu.Detach();
每个项的响应可以用classwizard的command消息
============================================
11.26
在MSDN中解释其
请问这个buffer是什么时候创建的,有多大? 问题点数:20、回复次数:6Top
你调用GetBuffer(int)时创建的
大小你可以自己定义
就是里面的int参数
ReleaseBuffer时
这个缓冲区的内容就是CString的内容了Top
CString本来就有段字符缓冲区
它会根据需要来改变缓冲区的大小
这段缓冲区应该是本来就有的
如果你传进去参数的比原来的大
它会自动改变Top
谢谢,还有,是不是我们每次使用CString.GetBuffer()之后都必须要调用CString.RealseBuffer()?Top
补充一点:CString 用引用计数
select ccode,ccname form t1 where 1=2 中的 where 1=2 如何理解
仅仅为了取得一个空的表结构
得到一个空表,表的字段为ccode,ccname
m_process.SetRange32()范围
UINT FPSignalThreadProc(LPVOID param)
{
CSameCheckDlg *pWnd=(CSameCheckDlg *)param;
m_list.SetItemData(nitem,result);
m_list.SortItems(MyCompareProc,0);
static int CALLBACK MyCompareProc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
return (int)(lParam2 - lParam1);
}
如果有必要,可以使用SetItemDataPtr()或SetItemData()将一个32位的指针(或一个DWORD的值)同列表框中的一个条目联系起来,并且在设置后可以通过调用GetItemDataPtr()或GetItemData()而获取。这样做的目的是可以将列表框中的条目同外部数据建立联系。例如:可以用这种方式非常方便地将一个包含有地址、电话号码和E-mail地址等信息的数据结构同列举在列表框中的持有人建立起关联。当从列表框中选中某个人时,可以同时得到有关该人的通讯信息。
============================================================
11.27
CFileDialog fdlg(true,".mdb",NULL,OFN_LONGNAMES|OFN_FILEMUSTEXIST,szFilter,NULL);//文件必须存在,OFN_LONGNAMES长文件名,否则只是8.3
separator系统分行.
通过App Wizard建立了一个dialog,我在其中加了一个edit,其control类的变量为m_focus,我希望在启动时把焦点设在这个edit上,且不改动原有的ok和cancel按钮,应该怎么做?在dialog的初始化函数中执行m_focus.setfocus();没用,原因是在edit控件加载完以后才加载按钮空间吗?
在VC中编缉你那个dialog的窗口时,按Ctrl+D ,然后第一个点一下你那个edit框,使它变成1 试试
不支持access2000
AfxGetModuleState()->m_dwVersion = 0x0601;
====================================
12.11
添加private数据
protected:
//{{AFX_MSG(CEx04aView)
// NOTE - the ClassWizard will add and remove member functions here.
// DO NOT EDIT what you see in these blocks of generated code !
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
private:
=======================================
12.14
在mfc中寻找WindowProc
要在你的继承类中实现, LRESULT CYourClass::WindowProc(UINT, WPARAM, LPARAM)
=================================
12.18
在C语言中对文件的记录是以字符(字节)为单位的。输入输出的数据流的开始和结束仅受程序控制而不受物理符号(如回车换行符)控制。也就是说,在输出时不以回车换行符作为记录的间隔(事实上C文件并不由记录构成)。我们把这种文件称为流式文件。
============================
12.19
CString
SpanIncluding() 从字符串中提取包含在指定字符数组内的字符的子串
============================================
12.21
1秒=1千毫秒 1毫秒=1千微秒 1微秒=1千纳秒所以0.1毫秒=0.1×1000×1000=100000纳秒(10万纳秒)
=======================================
2008.1.17
access的
sql语句中 空值判断(不是""(空格)) ,用or ** is NULL
如果是紧缩型的SQL语句,可以用( sql语句 or ** is NULL ) 判断
===============================================
2008.2.18
先在按钮的Style里选中Bitmap和Owener draw,然后把Caption改为ID的名称
加入一副图,图的ID 为按扭的ID加上U,F,X,D其中的一个,比如按钮ID为IDOK,那么图的ID就可以设为"IDOKU" 记得一定要加双引号,U代表按钮弹起时的图案,D代表压下时的,X代表按钮无用时的,F代表获得聚焦时的。
然后声明一个位图按钮类(CBitmapButton)的对象,调用AutoLoad函数,这个函数的两个参数分别是按钮的ID,和按钮父窗口的句柄
这样就可以把图显示在按钮上了
除了以上方法还有一些,如loadimage,loadbitmap,setbitmap,你可以看看msdn有关这些函数的解释和应用
位图按钮的实现方法:
首先,我们创建一个基于对话框的应用程序CmyDialog ;
Ι.MFC的CBitmapButton类,这也是最简单的功能最强的位图按钮。我们可以采取如下的步骤:
1. 为按钮指定唯一的按钮标题(此例子为OK按钮,这里设置按钮标题为OK)并选中Ownerdraw属性,然后在项目中加一些位图资源,并用名字标示这些资源而不要用数字ID,其ID分别为”OKU”、”OKD”、”OKF”、”OKX”(一定要加双引号),分别对应于按钮的“松开(Up)”、“按下(Down)”、“获得输入焦点(focused)”和“禁止(Disable)”状态。
2. 我们还要在对话框类中加入CBitmapButton m_aBmpBtn;数据成员。
3. 在初始化中为这个成员调用:
…
m_aBmpBtn. AutoLoad(IDOK,this);
…
点击编译按钮,成功后运行程序,哈哈,看看效果,我们的位图按钮已经建立了。
/*如果以上方法不行请检查你的BITMAP 资源,APPSTUDIO中,"OKU"和 "OKD" 等的资源名称都是需要用引号引起来的, AutoLoad不成功,很可能就是由此产生的。 */
改变CANCLE按钮的标题,可以设置其标题为ICON或者BITMAP :(这里我们演示了bitmap的用法,Icon按钮读者可以按照下面的代码处理)
Ⅱ.使用图标制作按钮
1. 打开ICON按钮的属性页,在Style中选中Icon 。
2. 在对话框类的头文件中定义成员变量(使用ClassWizard加入这个成员变量)
CButton m_ IconBtn;//对应于图标按钮
3. 创建相应的图标或者位图资源:
图标资源:IDI_ICONBUTTON
4.在初始化中加入如下代码:
…
//对应于图标按钮
HICON hIcon=AfxGetApp()->LoadIcon(IDI_ ICONBUTTON);
m_IconBtn.SetIcon(hIcon);
…
重新编译运行我们的程序,奇妙的图像按钮呈现在我们的眼前了。
Ⅲ.使用位图制作按钮
1. 打开BITMAP按钮的属性页,在Style中选中Bitmap。
2. 对话框类的头文件中定义成员变量(使用ClassWizard加入这个成员变量)
CButton m_IconBtn;
3.创建位图资源:
位图资源:IDB_BITMAPBUTTON
4.在初始化中加入如下代码:
//对应于位图按钮
…
HBITMAP hBmp=::LoadBitmap(AfxGetInstanceHandle(),
MAKEINTRESOURCE(IDB_ BITMAPBUTTON));
m_BmpBtn.SetBitmap(hBmp);
================================
2008.2.19
渐变色代码
CClientDC pDC(this);
CRect m_rcClient, rectangle;
this->GetClientRect(&m_rcClient);
int nWidth = m_rcClient.Width();
int nHeight = m_rcClient.Height();
for(int i=0; i<nWidth; i++)
{
rectangle.SetRect(i, 0, i+1, nHeight);
pDC.FillSolidRect(&rectangle, RGB(ColorR, ColorG, 255-MulDiv(i, 255, nWidth)));
}
1。在按钮上显示位图:
如果我们在对话框上拖了一个button,我们想在上面显示位图:
则将该button的属性改为bitmap(property-> style);
用class wizard 添加一个button的成员变量m_bmpBtn;
在对话框类重添加一个成员变量CBitmap m_bmp;
建立一个资源位图IDB_TEST;
在OnInitDialog中:
m_bmp.LoadBitmap(IDB_TEST);
m_bmpBtn.SetBitmap((HBITMAP)m_bmp);
第一种:
Button属性页里Style的Bitmap点上
CBitmap Bitmap;
Bitmap.LoadBitmap(IDB_BITMAP1);
HBITMAP hBitmap=(HBITMAP)Bitmap.Detach();
CButton *pButton=(CButton*)GetDlgItem(IDCANCEL);
pButton->SetBitmap(hBitmap);
感觉效果不是很好。因为图片不会自动拉伸。
第二种:
可以采用CButtonST控件,挺好用的,比MFC的那些封装好用。
第三种:
把button按钮属性设置为ower draw
然后映射onDrawItem消息
在ondraw函数内自己绘制就可以了
void CUi6Dlg::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
{
if(nIDCtl == IDC_HELLO_CFAN)
{
//绘制按钮框架
UINT uStyle = DFCS_BUTTONPUSH;
//是否按下去了?
if (lpDrawItemStruct->itemState & ODS_SELECTED)
uStyle |= DFCS_PUSHED;
CDC dc;
dc.Attach(lpDrawItemStruct->hDC);
dc.DrawFrameControl(&lpDrawItemStruct->rcItem, DFC_BUTTON, uStyle);
//输出文字
dc.SelectObject(&m_Font);
dc.SetTextColor(RGB(0, 0, 255));
dc.SetBkMode(TRANSPARENT);
CString sText;
m_HelloCFan.GetWindowText(sText);
dc.TextOut(lpDrawItemStruct->rcItem.left + 20, lpDrawItemStruct->rcItem.top + 20, sText);
//是否得到焦点
if(lpDrawItemStruct->itemState & ODS_FOCUS)
{
//画虚框
CRect rtFocus = lpDrawItemStruct->rcItem;
rtFocus.DeflateRect(3, 3);
dc.DrawFocusRect(&rtFocus);
}
return;
}
CDialog::OnDrawItem(nIDCtl, lpDrawItemStruct);
}
第四种:
|
设置背景图片
把对话框带图的文字控件背景设置为透明
pDC->SetBkMode(TRANSPARENT);
return (HBRUSH)GetStockObject(NULL_BRUSH);
设置静态文本框的背景为透明
与静态文本框相关的颜色层次有:对话框背景色,文本框背景色,文字颜色和文字背景色。
相关函数有:
-
pDC->SetTextColor(RGB(150, 100, 100)) :设置文字颜色的函数
-
pDC->SetBkColor(RGB(0,125,1)) :设置文字背景色的函数
-
pDC->SetBkMode(TRANSPARENT):设置文字背景色是否透明 ,如果设置为TRANSPARENT,则设置文字背景色的函数无效。
文本框的背景色缺省为对话框背景色,如果文本框的下面有图形,则使用NULL_BRUSH使文本框透明,代码如下:
if ( nCtlColor==CTLCOLOR_STATIC||nCtlColor==CTLCOLOR_BTN||nCtlColor==CTLCOLOR_MAX )
{
pDC->SetBkMode(TRANSPARENT);
pDC->SetTextColor(RGB(255,255,255));
return (HBRUSH)::GetStockObject(NULL_BRUSH);
}
适合VC6.0
========================================
2.20
VC++6.0中如何制作自绘的按钮(各种颜色,各种形状)并实现它
1、在资源中定义一个自画的按钮(Owner draw),假设ID为IDC_MYBUTTON
2、重载DLG的OnDrawItem函数,添加如下代码:
...
if(nIDCtl == IDC_MYBUTTON)
{
CBrush br(clrBack);
CRect rc;
GetDlgItem(IDC_MYBUTTON)->GetClientRect(rc);
CClientDC dc(GetDlgItem(IDC_MYBUTTON));
dc.FillRect(rc, &br);
br.DeleteObject();
}
else
CDialog::OnDrawItem(nIDCtl, lpDrawItemStruct);
...
以上代码是我现在一段程序中用的,应该没什么问题。
另外,如果你还要设置按钮形状(PPMM形?),应该使用SetWindowRgn函数,
可以在OnInitDialog中调用。不过我没有试过:)
============================
2.22
撤销资源(暂未知道作用)
HRSRC res = FindResource(NULL,MAKEINTRESOURCE(IDR_SWF1),"swf");
HGLOBAL gl = LoadResource(NULL,res);
LPVOID lp = LockResource(gl);
CString strFileName("C://tianshi.swf");
HANDLE fp = CreateFile(strFileName,GENERIC_WRITE,FILE_SHARE_READ,NULL,CREATE_NEW,0,NULL);
DWORD aa;
if(!WriteFile(fp,lp,::SizeofResource(AfxGetResourceHandle(),res),&aa,NULL) )
return ;
CloseHandle(fp);
FreeResource(lp);
active
IDC_SHOCKWAVEFLASH
在对话框点右键有提示
SHOCKWAVEFLASH可以读取磁盘上的SWF,不过局限为磁盘上。
====================================
2008.3.20
ctabctrl关键代码
CPAGESG pagesg;
CPAGEZQ pagezq;
必须为类变量,否则不显示
child属性无标题,
CPAGESG pagesg;
CPAGEZQ pagezq;
m_table.InsertItem(0,_T("武林三国"));
m_table.InsertItem(1,_T("武林足球"));
pagesg.Create(IDD_DPAGESG,GetDlgItem(IDC_TABLE));
pagezq.Create(IDD_DPAGEZQ,GetDlgItem(IDC_TABLE));
CRect rs;
m_table.GetClientRect(rs);
rs.top+=20;
rs.bottom-=4;
rs.left+=4;
rs.right-=4;
pagesg.MoveWindow(&rs);
pagezq.MoveWindow(&rs);
pagesg.ShowWindow(true);
m_table.SetCurSel(1);
然后用于选择页的:
在Tab的TCN_SELCHANGE里面写显示隐藏代码就可以了
int nIndex;
nIndex = m_ctrlTab.GetCurSel();
m_dlg1.ShowWindow(SW_HIDE);
m_dlg2.ShowWindow(SW_HIDE);
m_dlg3.ShowWindow(SW_HIDE);
switch(nIndex)
{
case 0:
m_dlg1.ShowWindow(SW_SHOW);
break;
case 1:
m_dlg2.ShowWindow(SW_SHOW);
break;
case 2:
m_dlg3.ShowWindow(SW_SHOW);
break;
}
方法一:添加ICON图标
1. 新建一个基于对话框的项目:Test
2. 在类CTestDlg中, 添加两个变量:
CToolBarCtrl m_ToolBar1;
CImageList m_ImageList;
3.添加图标(例5个.icon图标)
4. 在#include "TestDlg.h"中 添加 #define ID_TOOLBAR1 1000
5. 在OnInitDialog()初始化:
const int ARR_MAX = 5;
m_ImageList.Create(32, 32, ILC_COLOR32 | ILC_MASK, 0, 0);
m_ToolBar1.EnableAutomation();
m_ToolBar1.Create(WS_CHILD | WS_VISIBLE, CRect(0, 0, 0, 0), this, ID_TOOLBAR1);
UINT Resource[ARR_MAX] = {IDI_ICON1, IDI_ICON2, IDI_ICON3, IDI_ICON4, IDI_ICON5};
int i;
TBBUTTON button[ARR_MAX];
for(i = 0; i < ARR_MAX; i++)
{
m_ImageList.Add(::LoadIcon(::AfxGetResourceHandle(), MAKEINTRESOURCE(Resource[i])));
}
m_ToolBar1.SetImageList(&m_ImageList);
for(i = 0; i < ARR_MAX; i++)
{
button[i].dwData = 0;
button[i].fsState = TBSTATE_ENABLED;
button[i].fsStyle = TBSTYLE_BUTTON;
button[i].iBitmap = i;
}
m_ToolBar1.AddButtons(ARR_MAX, button);
//TBBUTTON Wrap;//创建一个分隔条
//Wrap.dwData = 0;
//Wrap.fsState = TBSTATE_ENABLED;
//Wrap.fsStyle = TBSTYLE_SEP;
//m_ToolBar1.InsertButton(3, &Wrap);
//m_ToolBar1.AutoSize();
m_ToolBar1.SetStyle(TBSTYLE_FLAT | CCS_TOP);
——————————————————————————————————————
方法二:自己绘制的
1. 添加资源(一个IDR_TOOLBAR1)
2. 在类CTestDlg中, 添加变量:
CToolBar m_ToolBar;
3. 初始化中添加:
if(!m_ToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_ALIGN_TOP) || !m_ToolBar.LoadToolBar(IDR_TOOLBAR1))
{
TRACE0("Failed to create toolbar!");
return -1;
}
RepositionBars(AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST, 0);
m_ToolBar.ShowWindow(SW_SHOW);
主要内容:
1, 概要。
2, 常用函数
3, 实例。
4, 动态建立工具条
5, 在工具栏中嵌控件
6, 用对话框加位图按钮作工具条
我们可以在资源编辑器的ToolBar上单击右键,选择Insert ToolBar,选中一个工具栏后,在右边双击它的一项就可以编辑了。我们可以用图形工具条及颜色盒画它的外表,它的属性有ID,长,宽及鼠标指向它时的说明。
一般CToolBar定义在CMainFrame中,其实现在CMainFrame的OnCreate函数中完成。
if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
{
TRACE0("Failed to create toolbar\n");
return -1; // fail to create
}
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndToolBar);
DWORD dwStu;e = WS_CHILD | WS_VISIBLE |CBRS_TOP,
UINT nID = AFX_IDW_TOOLBAR);
pParentWnd指定所属窗口。
dwStyle 指定工具栏风格
CBRS_TOP 允许工具栏位于框架窗口顶端。
CBRS_BOTTOM 允许工具栏位于框架窗口底端
CBRS_NOALIGN 父窗口改变尺寸后工具栏位置不变
CBRS_TOOLTIPS 工具栏显示提示条
CBRS_SIZE_DYNAMIC 工具幸是动态的
CBRS_SIZE_FIXED 工具栏是固定的
CBRS_FLOATING 工具栏是浮动的
CBRS_FLYBY 当鼠标从命令按钮上掠过时显示提示信息
CBRS_HIDE_INPLACE 工具栏对用户不可见
SetButtonStyle()函数用来设定命令按钮的风格或间隔区,或设为一组,按钮的风格决定了按钮的外貌和对用户的反应方式.
Void SetButtonStyle(int nIndex,UINT nStyle);
nIndex 指定工具栏中按钮或间隔的索引号.
nStyle TBBS_BUTTON 标准按钮,此为默认值
TBBS_SEPARATOR 间隔区
TBBS_CHECKBOX 自动确认区
TBBS_GROUP 标记为一组按钮的开始
TBBS_CHECKGROUP 标记为一组确认框的开始
ControlBar类的EnableDocking函数和CFrameWnd类的DockControlBar函数配合,设定工具栏的可活动性.
Void EanbleDocking(DWORD dwStyle)
CBRS_ALIGN_TOP 允许工具栏位于客户区上侧
CBRS_ALIGN_BOTTOM 允许工具栏位于客房区下侧
CBRS_ALIGN_LEFT 允许工具栏位于客户区左侧
CBRS_ALIGN_RIGHT 允许工具栏位于客户区右侧
CBRS_ALIGN_ANY 允许工具栏位于客户区的任意位置
CBRS_FLOAT_MULTI 允许多个控制栏在一个迷你框架窗口中浮动
Void DockControlBar(….)
pBar 要浮动的控制栏指针.
nDockBarID指定允许浮动的位置,或为0则不允许浮动,可以由下列值组合而成:
AFX_IDW_DOCKBAR_TOP 控制栏置于框架窗口上侧;
AFX_IDW_DOCKBAR_BOTTOM 控制栏置于框架窗口下侧
AFX_IDW_DOCKBAR_LEFT 控制栏置于框架窗口左侧
AFX_IDW_DOCKBAR_RIGHT 控制栏置于框架窗口右侧
改变工具栏的命令按钮风格,工具栏的按钮一般默认为命令按钮,当放开标鼠标,命令按钮就”弹出来”,如果我们希望命令按钮能留在被按上的状态,就可以把命令按钮的风格设为确认框。在ON_UPDATE_COMMAND_UI消息处理函数中,使用SetCheck()成员函数和SetRadio()成员函数改变按钮状态。
SetCheck()的参数0表示删除状态,1表示确认状态,2表示不确认状态
SetRadio()的参数0表示删除状态,非0表示确认状态。
我们用应用程序向导建立一个单文档程序,在工具栏中添加按钮,ID设定为ID_TIME.在CMainFrame类添加一个布尔数据类型m_bTime,初始值为false.
Ctrl+w添加ID_TIME的ON_COMMANDT和ON_UPDATE_COMMAND_U消息响应函数。
void CMainFrame::OnShowTime()
{
m_bTime = ! m_bTime;
}
void CMainFrame::OnUpdateShowTime(CCmdUI * pCmdUI)
{
pCmdUI ->SetCheck(m_bTime);
}
注意如果有一个同ID的菜单,它会自动根据按钮的情况打上钩钩。
事实上我们可以不用toolbar资源建立一个工具条。代码如下:
UINT nID[]=
{ID_FILE_NEW,
ID_FILE_OPEN,
ID_TIME
};
m_wndToolBar.Create(this);
m_wndToolBar.LoadBitmap(IDB_BITMAP1);
m_wndToolBar.SetButtons(nID,sizeof(nID)/sizeof(UINT));
其中位图的大小要合适,否则会影响美观,最后一行让几个ID与工具栏的按钮和相关。
如果想设置每个按钮的风格,可以将最后一行后面加:
m_wndToolBar.SetButtonStyle(1,TBBS_SEPARATOR);
也可m_wndToolBar.Create(this);
m_wndToolBar.LoadBitmap(IDB_BITMAP1);
m_wndToolBar.SetButtons(NULL,3);
m_wndToolBar.SetButtonInfo(0,ID_FILE_NEW,TBBS_BUTTON,0);
m_wndToolBar.SetButtonInfo(1,ID_FILE_OPEN,TBBS_BUTTON,2);
1, 定义一个编辑控件对象,不能是局部变量,否则会被释放掉。
2, 调用Create,唯一要注意的是位置要在工具条的地盘上。
CRect rect;
m_wndToolBar.GetItemRect(1,&rect);
edit.Create(WS_CHILD|WS_VISIBLE,rect,&m_wndToolBar,ID_EDIT);
插入一个对话框,Styles的style设为child,border设为none.
在CMainFrame中m_wndToolBar的改成CDialogBar,并加一个CBitmapButton bb;
把建立工具条的那一句改为:
m_wndToolBar.Create(this,IDD_DIALOG1,WS_CHILD|WS_VISIBLE|CBRS_TOP,AFX_IDW_STATUS_BAR);
最后一上ID 同自己随便确定。Ctrl+F5,一个极不美观的工具条就出来了。
对按钮进行整理,它们的处理函数仍然上Ctrl+w加。将按钮Styles的Owner drawer和bitmap钩上。在刚才的地方加一句。
bb.AutoLoad(IDC_BUTTON1,&m_wndToolBar);
注意你需要加三幅位图(一幅也可以)。如你的按钮的名字为X,刚三幅位图的名字分别为”XUP”,”XDOWN”,”XFOCUS”,简写为”XU”,”XD”,”XF”.
工具栏(ToolBar)是一种非常方便的控件,能大大增加用户操作的效率,但是基于对话框的程序,却不能像使用编辑框(Edit Box)和列表框(List Box)一样,方便地增加工具栏控件。本文将介绍一种在对话框中加入工具栏的方法。
一、 技术要点分析
所有的Windows控件(包括工具栏、编辑框等)都派生自CWnd类,这就意味着,我们可以用窗口类的Create()函数把它们“创建”并显示到另一个窗口(例如对话框)上。把工具栏加入到对话框中正是使用了这样的一种方法。
通常,我们使用CToolBarCtrl类(派生自CWnd类)来创建并管理工具栏控件。使用这个类创建一条工具栏的一般步骤如下:
1.派生一个CToolBarCtrl的对象;
2.调用CToolBarCtrl::Create函数创建工具栏对象;
3.调用CToolBarCtrl::AddBitmap()和CToolBarCtrl::AddString()为工具栏对象加入位图和提示信息;
4.派生一个TBUTTON数组对象进行工具栏中各按钮的具体设置;
5.修改主窗口的OnNotify()函数,以显示工具栏上的提示信息。
以上步骤在下面的范例代码中会有具体体现。
二、 范例程序的建立与主要代码分析
利用Visual C++ 的向导生成一个基于对话框的程序,命名为ToolBarInDial。修改主对话框样式如图1。绘出一条工具栏的位图并建立一选单,设置几个子选单项,然后建立一组工具栏的提示信息串(String Table),一旦鼠标在工具栏某项上停留,就会显示提示信息。下面给出程序中的主要代码。
在主对话框CToolBarInDialDlg的类定义中有如下的变量说明:
CToolBarCtrl ToolBar;
int ButtonCount;
int ButtonBitmap;
BOOL DoFlag;
TBBUTTON m_Button[5];
//设置工具栏上具体信息的变量数组
//主对话框的初始化函数
BOOL CToolBarInDialDlg::OnInitDialog()
{
RECT rect;
//设置工具栏的显示范围
rect.top=0; rect.left=0; rect.right=48; rect.bottom=16;
ToolBar.Create(WS_CHILD|WS_VISIBLE|CCS_TOP|TBSTYLE_TOOLTIPS|CCS_ADJUSTABLE,rect,this,0);
//建立工具栏并设置工具栏的样式
ButtonBitmap=ToolBar.AddBitmap(5,IDB_PLAY); //加入工具栏的位图
ButtonString=ToolBar.AddString(IDS_FIRST);//加入工具栏的提示信息
//以下代码开始设置各具体的按钮
m_Buttons[ButtonCount].iBitmap=
ButtonBitmap+ButtonCount; //ButtonCount初值为0
m_Buttons[ButtonCount].idCommand=ID_PLAY; //工具栏与选单上某子项对应
m_Buttons[ButtonCount].fsState=TBSTATE_ENABLED;
//设置工具栏按钮为可选
m_Buttons[ButtonCount].fsStyle=TBSTYLE_BUTTON;
//设置工具栏按钮为普通按钮
m_Buttons[ButtonCount].dwData=0;
m_Buttons[ButtonCount].iString=IDS_LAST;
++ButtonCount;
//类似地设置第二个按钮
m_Buttons[ButtonCount].iBitmap=ButtonBitmap+ButtonCount;
m_Buttons[ButtonCount].idCommand=ID_STOP;
m_Buttons[ButtonCount].fsState=TBSTATE_ENABLED;
m_Buttons[ButtonCount].fsStyle=TBSTYLE_BUTTON;
m_Buttons[ButtonCount].dwData=0;
m_Buttons[ButtonCount].iString=IDS_NEXT;
++ButtonCount;
……//省略设置剩下的按钮的代码
ToolBar.AddButtons(ButtonCount,m_Buttons);
//为工具栏加入按钮并显示在对话框中
return TRUE;
}
//当鼠标在工具栏上停留时,调用这个函数来显示提示信息
BOOL CToolBarInDialDlg::OnNotify(WPARAM wParam, LPARAM lParam, LRESULTpResult)
{
TOOLTIPTEXTtt;
tt=(TOOLTIPTEXT)lParam;
CString Tip;
switch(tt->hdr.code)
{
case TTN_NEEDTEXT:
//该信息表明要求显示工具栏上的提示
switch(tt->hdr.idFrom)
{
case ID_PLAY:
Tip.LoadString(IDS_FIRST); //设置对应于工具栏上ID_PLAY的按钮的提示信息
break;
case ID_STOP:
Tip.LoadString(IDS_NEXT);
//IDS_FIRST,IDS_NEXT等为一系列CString串
break;
……//类似地设置剩下按钮的提示信息
}
strcpy(tt->szText,(LPCSTR)Tip);
//显示提示信息
break;
}
return CDialog::OnNotify(wParam, lParam, pResult);
}
//该演示程序的工具栏能由用户定制,随时增加或删除工具栏中的某一项
void CToolBarInDialDlg::OnApply()
{
switch(DoFlag) //用户选择了增加或删除工具栏中的“退出”按钮
{
case TRUE: //增加工具栏上的“退出”按钮
m_Buttons[ButtonCount].iBitmap=ButtonBitmap+ButtonCount;
m_Buttons[ButtonCount].idCommand=ID_QUIT;
m_Buttons[ButtonCount].fsState=TBSTATE_ENABLED;
m_Buttons[ButtonCount].fsStyle=TBSTYLE_BUTTON;
m_Buttons[ButtonCount].dwData=0;
m_Buttons[ButtonCount].iString=IDS_FIRST;
ToolBar.InsertButton(ButtonCount,&&m_Buttons[ButtonCount]);
//根据m_Buttons的信息在工具栏的尾部加上一个按钮
break;
case FALSE:
if(ToolBar.GetButtonCount()==4) //删除工具栏上某一特定位置的按钮
{
ToolBar.DeleteButton(3);
//删除工具栏上某一按钮
}
break;
}
}
void CToolBarInDialDlg::OnPlay() //响应函数举例
{
……
//对应选单项的响应函数
}
以上程序在中/英文Windows 98、VC++ 6.0环境下编译通过,运行正常。图2为运行中的有工具栏的对话框程序。
===============================
2008.4.7
EXCEL操作代码
#include "afxdb.h"
#include "odbcinst.h"
void CEXCEL_1Dlg::OnBreadexcel()
{
CDatabase database;
CString sSql;
CString sItem1, sItem2;
CString sDriver;
CString sDsn;
CString sFile = "C:\\DEMO.xls";// 将被读取的Excel文件名
// 检索是否安装有Excel驱动 "Microsoft Excel Driver (*.xls)"
sDriver = GetExcelDriver();
if (sDriver.IsEmpty())
{
// 没有发现Excel驱动
AfxMessageBox("没有安装Excel驱动!");
return;
}
// 创建进行存取的字符串
sDsn.Format("ODBC;DRIVER={%s};DSN='''';DBQ=%s", sDriver, sFile);
TRY
{
// 打开数据库,建立与这个Excel对应的Database
database.Open(NULL, false, false, sDsn);
CRecordset recset(&database);
// 设置读取的查询语句.demo.xls并非文件名,需要在excel中进行//设置,具体文章最后有讲
// sSql = "SELECT Age, Name FROM [DEMO$]";
sSql = "SELECT Adr FROM [DEMO$]";
// 执行查询语句,打开表格
recset.Open(CRecordset::forwardOnly, sSql, CRecordset::readOnly);
// 获取查询结果
while (!recset.IsEOF())
{
//读取Excel内部数值
recset.GetFieldValue("Adr", sItem1);
// recset.GetFieldValue("Name", sItem1);
// recset.GetFieldValue("Age", sItem2);
// 移到下一行
recset.MoveNext();
}
// 关闭数据库
database.Close();
MessageBox(sItem1);
MessageBox(sItem2);
}
CATCH(CDBException, e)
{
// 数据库操作产生异常时...
AfxMessageBox("数据库错误: " + e->m_strError);
}
END_CATCH;
}
CString CEXCEL_1Dlg::GetExcelDriver()
{
char szBuf[2001];
WORD cbBufMax = 2000;
WORD cbBufOut;
char *pszBuf = szBuf;
CString sDriver;
// 获取已安装驱动的名称(涵数在odbcinst.h里)
if (!SQLGetInstalledDrivers(szBuf, cbBufMax, &cbBufOut))
return "";
// 检索已安装的驱动是否有Excel...
do
{
if (strstr(pszBuf, "Excel") != 0)
{
//发现 !
sDriver = CString(pszBuf);
break;
}
pszBuf=strchr(pszBuf,'\0')+1;
}
while (pszBuf[1] != '\0');
return sDriver;
}
===================
4.8
线程中不能用UPDATEDATA用消息代替
void FORONEPEOPLE::MyUpdate()
{
UpdateData(false);
}
->MyUpdate就可以了听说,原因在线程堆栈的问题,你调用成员函数就转过堆栈了,所以可以
也不行
用
CEdit * e=(CEdit *)fr->GetDlgItem(IDC_ETIME);
e->SetWindowText(fr->m_etime);
终于行了,跳过updatedata
AfxEndThread(1);内部结速线程
终止线程有三种途径,线程可以在自身内部调用AfxEndThread()来终止自身的运行;可以在线程的外部调用BOOL TerminateThread( HANDLE hThread, DWORD dwExitCode )来强行终止一个线程的运行,然后调用CloseHandle()函数释放线程所占用的堆栈;第三种方法是改变全局变量,使线程的执行函数返回,则该线程终止。
CEvent 类提供了对事件的支持,
BOOL CEvent::SetEvent();
将 CEvent 类对象的状态设置为有信号状态。如果事件是人工事件,则 CEvent 类对象保持为有信号状态,直到调用成员函数ResetEvent()将 其重新设为无信号状态时为止。如果CEvent 类对象为自动事件,则在SetEvent()将事件设置为有信号状态后,CEvent 类对象由系统自动重置为无信号状态。
BOOL CEvent::ResetEvent(); 该函数将事件的状态设置为无信号状态,并保持该状态直至SetEvent()被调用时为止。由于自动事件是由系统自动重置,故自动事件不需要调用该函数。如果该函数执行成功,返回非零值,否则返回零。我们一般通过调用WaitForSingleObject函数来监视事件状态。前面我们已经介绍了该函数。由于语言描述的原因,CEvent 类的理解确实有些难度,但您只要通过仔细玩味下面例程,多看几遍就可理解。
WaitForSingleObject();
第一参数为线程句柄,对象
第二参数为INFINITE表示一直等待
CEvent要注意人工还是自动
1、CEvent(BOOL bInitiallyOwn=FALSE, BOOL bManualReset=FALSE, LPCTSTR lpszName=NULL, LPSECURITY_ATTRIBUTES lpsaAttribute=NULL);
- bInitiallyOwn:指定事件对象初始化状态,TRUE为有信号,FALSE为无信号;
- bManualReset:指定要创建的事件是属于人工事件还是自动事件。TRUE为人工事件,FALSE为自动事件;
- 后两个参数一般设为NULL,在此不作过多说明。
(一) 临界区
临界区对应着一个CcriticalSection对象,当线程需要访问保护数据时,调用临界区对象的Lock()成员函数;当对保护数据的操作完成之后,调用临界区对象的Unlock()成员函数释放对临界区对象的拥有权,以使另一个线程可以夺取临界区对象并访问受保护的数据。
CCriticalSection Section;
(二)互斥
互斥与临界区很相似,但是使用时相对复杂一些,它不仅可以在同一应用程序的线程间实现同步,还可以在不同的进程间实现同步,从而实现资源的安全共享。互斥与Cmutex类的对象相对应,使用互斥对象时,必须创建一个CSingleLock或CMultiLock对象,用于实际的访问控制,因为这里的例子只处理单个互斥,所以我们可以使用CSingleLock对象,该对象的Lock()函数用于占有互斥,Unlock()用于释放互斥。
#include "afxmt.h"
CMutex Section;
=========================
4.10
注意规则DLL里面,CPP文件要引入对应的H文件
否则找不到导出函数,用DEPENECY查为空.
#include "lib.h"
折腾了一个晚上
随机数:例子
int rd=rand()%100;
CString str;
str.Format("%d",rd);
MessageBox(str);
=======================================
4.15
void CEXCEL080414Dlg::Init1()
{
SetTimer(1,2000,NULL);
}
void CEXCEL080414Dlg::OnTimer(UINT nIDEvent)
{ //主要看教程例子做欢迎界面,2秒后出现!!!,原来是直接退出界面的
// TODO: Add your message handler code here and/or call default
KillTimer(1);
MessageBox("!!!");
CDialog::OnTimer(nIDEvent);
}
再次确认退出
if(MessageBox("确认是否退出工厂库存表","系统提示",MB_YESNO|MB_ICONQUESTION) == IDYES)
{
CDialog::OnCancel();
}
=================================
4.17
sql语句中
sSql = "SELECT * FROM [Sheet1$] where 规格型号说明 = 'SP3232EEA/SSOP16'
字符匹配.一时间忘记了
数值的不需要''
不为空
<>null
is not null
=======================================
4.18
无效游标的另一种可能是
sql语句错误
例如
"SELECT * FROM [Sheet1$] where 规格型号说明 = 'SE5167ALN/SOT23-3 或者AP2210N-3.3/SOT23-3' "
要确保'SE5167ALN/SOT23-3 或者AP2210N-3.3/SOT23-3' 记录在内
顺便贴个动态行集(Dynasets)的概念
动态行集能保持与其他用户所做的更改保持同步。快照集则是数据的一个静态视图。
每种形式在记录集被打开时都提供一组记录,所不同的是,当在一个动态行集里滚动到一条记录时,由其他用户或应用程序中的其他记录集对该记录所做的更改会相应地显示出来。
CDatabase *db;
rs.m_pDatabase=db;
与
CRecordset recset(&database);
recset.m_pDatabase = &database;
等价,获取指针
=======================================
2008.08.23
//将CString 型IP地址在IPAddressCtrl中显示
CString strIP="192.168.0.10";
DWORD dwIP;
dwIP = inet_addr(strIP);
unsigned char *pIP = (unsigned char*)&dwIP;
m_ipAddr.SetAddress(*pIP, *(pIP+1), *(pIP+2), *(pIP+3));
//将IPAddressCtrl中的IP地址获得并转换成CString型
unsigned char *pIP;
CString strIP;
DWORD dwIP;
m_ipAddr.GetAddress(dwIP);
pIP = (unsigned char*)&dwIP;
strIP.Format("%u.%u.%u.%u",*(pIP+3), *(pIP+2), *(pIP+1), *pIP);
系统托盘关闭
NOTIFYICONDATA nid;
nid.cbSize=(DWORD)sizeof(NOTIFYICONDATA);
nid.hWnd=this->m_hWnd;
nid.uID=IDR_NIDICON;
nid.uFlags=NIF_ICON|NIF_MESSAGE|NIF_TIP;
nid.uCallbackMessage=WM_SHOWTASK;
nid.hIcon=LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDR_NIDICON));
strcpy(nid.szTip,"服务端");
Shell_NotifyIcon(NIM_DELETE,&nid);
exit(1);
===============================================
2008.08.24
sockaddr_in
sin_addr.s_addr=inet_addr("127.0.0.1");
指定某IP
评论