正文

学习VC++日记(二)2008-03-20 14:55:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/sword2008/30815.html

分享到:

=============================================

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中解释其功能为:Returns   a   pointer   to   the   internal   character   buffer   for   the   CString   object。  
        请问这个buffer是什么时候创建的,有多大? 问题点数:20、回复次数:6Top

你调用GetBuffer(int)时创建的  
  大小你可以自己定义  
  就是里面的int参数  
  ReleaseBuffer时  
  这个缓冲区的内容就是CString的内容了Top

CString本来就有段字符缓冲区  
  它会根据需要来改变缓冲区的大小  
  这段缓冲区应该是本来就有的  
  如果你传进去参数的比原来的大  
  它会自动改变Top

谢谢,还有,是不是我们每次使用CString.GetBuffer()之后都必须要调用CString.RealseBuffer()?Top

补充一点:CString   用引用计数管理内部的字符串缓冲区,这个缓冲区有可能是被多个   CString   共享的,GetBuffer   调用使   CString   认为你需要写入这个缓冲区,为了避免同时更改其他   CString   ,CString   如果发现有其他   Cstring   共享缓冲区,就   Release   旧缓冲区重新申请新缓冲区。ReleaseBuffer   的作用是通知   CString   更改完毕,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);
}

第四种:



1,按钮属性 Onwer Drew选上,按钮ID: IDC_BUTTON1
2,定义private变量:
CBitmapButton m_button;
3,在初始化里边
m_button.LoadBitmaps(IDB_BITMAP1, IDB_BITMAP2);//IDB_BITMAP1:平时;IDB_BITMAP2:按下
m_button.SubclassDlgItem(IDC_BUTTON1, this);
m_button.SizeToContent();
这种方法还可以。

 

设置背景图片

把对话框带图的文字控件背景设置为透明

pDC->SetBkMode(TRANSPARENT);  
 return   (HBRUSH)GetStockObject(NULL_BRUSH);

设置静态文本框的背景为透明

与静态文本框相关的颜色层次有:对话框背景色,文本框背景色,文字颜色和文字背景色。
相关函数有:

  1. pDC->SetTextColor(RGB(150, 100, 100)) :设置文字颜色的函数
  2. pDC->SetBkColor(RGB(0,125,1)) :设置文字背景色的函数
  3. 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;
}

 

VC添加工具栏

方法一:添加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中,其实现在CMainFrameOnCreate函数中完成。

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

 

 

Bool Create(CWnd *pParentWnd,

          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_TIMEON_COMMANDTON_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);

 

用对话框加位图按钮作工具栏。

插入一个对话框,Stylesstyle设为child,border设为none.

CMainFramem_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加。将按钮StylesOwner drawerbitmap钩上。在刚才的地方加一句。

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, LRESULTpResult)

  {

  TOOLTIPTEXTtt;

  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

阅读(13554) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册