正文

学习VC++日记(总)2008-12-19 16:18:00

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

分享到:

2007.8.6用了两天时间搞了配置和安装简单接触了一下对话框书上都可以掌握,勉强通过。

 

8.7,学习组合框, 先建立一public all变量,最好不用public ,但是刚接触没其他办法。

 

all=m_combox.GetCurSel();

 CString str;


    m_combox.GetLBText(all, str);

 AfxMessageBox(str);

 

就可以实现简单的组合框选择数据项问题。

listcontrul那里用得少。

 

然后是了解自定义消息,消息映射估计怎么也花2天时间。

 

网上找的

#include <afxwin.h>
#include "WMtest.h"

CMyApp myApp;

BOOL CMyApp::InitInstance()
{
 m_pMainWnd = new CMainWindow;

 m_pMainWnd->ShowWindow(m_nCmdShow);
 m_pMainWnd->UpdateWindow();
 return TRUE;
}

BEGIN_MESSAGE_MAP(CMainWindow,CFrameWnd)
 ON_WM_PAINT()
 ON_WM_LBUTTONDOWN()
 file://增加消息映射
 ON_MESSAGE(WM_MY_MSG,OnMyMessage)
END_MESSAGE_MAP()

CMainWindow::CMainWindow()
{
 Create(NULL,_T("The 1st MFC Application"));
}

void CMainWindow::OnPaint()
{
 CPaintDC dc(this);
 CRect rect;
 GetClientRect(&rect);
}

file://消息响应函数
LRESULT CMainWindow::OnMyMessage(WPARAM wParam,LPARAM lParam)
{
 AfxMessageBox("MyMsg received");
 return 0;
}

void CMainWindow::OnLButtonDown(UINT nFlags, CPoint point)
{
 file://响应鼠标左键按下来产生那个自定义的消息
 PostMessage(WM_MY_MSG,0,0);
}
.CPP
上面那个是.H
//这里新加一句,自定义消息
#define WM_MY_MSG WM_USER+101

class CMyApp : public CWinApp
{
public:
 virtual BOOL InitInstance();
};

class CMainWindow : public CFrameWnd
{
public:
 CMainWindow();

protected:
 afx_msg void OnPaint();
 file://增加消息响应函数的声明
 afx_msg LRESULT OnMyMessage(WPARAM wParam,LPARAM lParam);
 afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
 DECLARE_MESSAGE_MAP()
};

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

总结:

1先定义宏:#define WM_MY_MSG WM_USER+N(N>100)

2://增加消息响应函数的声明,大概是在.h头文件
 afx_msg LRESULT OnMyMessage(WPARAM wParam,LPARAM lParam);
 afx_msg void OnLButtonDown(UINT nFlags, CPoint point);

3://消息响应函数,大概是在CPP里面添加
LRESULT CMainWindow::OnMyMessage(WPARAM wParam,LPARAM lParam)
{
 AfxMessageBox("MyMsg received");
 return 0;
}

void CMainWindow::OnLButtonDown(UINT nFlags, CPoint point)
{
 应鼠标左键按下来产生那个自定义的消息
 PostMessage(WM_MY_MSG,0,0);
}

4建立消息映射,在没有钥匙的那个函数上执行

//增加消息映射
 ON_MESSAGE(WM_MY_MSG,OnMyMessage)

 

5以上是一种方法另外还有一种有时间多看看消息内部机制熟悉MFC和API。

 

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

8.8

继续消息

 

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

8.9

很多控件类都是继承CWnd来的?

 

8.10

串口编程

MSCOMM不是工具控件,所以使用的时候要添加,具体就是Project->Add To Project->Commponents and Controls 然后你在一堆ActiveX中找到Miscrosoft Communications Control,Version 6.0

工程那里添加

 

 

------------------------------------------------------------------------------------------------------

csdn的回复

1

我用API编程,感觉难度嘛,入门了也不难,串口通讯分大致几个步骤,
1:打开串口:包括对串口缓冲区的定义,超时设置,DCB结构设置等等
2:向串口读入缓冲区发送通讯协议所规定的命令
3:仪器接收到命令后会向读出缓冲区回馈信息,你需要去读取
4:对仪表的回馈信息进行处理,提取有效信息等,
这过程大致的难点:
第1步没有什么难度,网上有代码给你抄袭
第2步要注意发送命令的格式:字符格式或是16进制格式等等,你需要研读通讯协议,根据协议的命令格式,自编命令,建议你和厂商多联系,要有死缠烂打的精神
第3步没有太多难度
第4步需要一些处理,因为不同厂商定制的协议不同,反馈信息也不同,需要你有熟练的字符串处理能力,进制转换能力,数学算法等
另外串口编程很有可能需要涉及到数据库编程,毕竟数据多数情况需要保存嘛!

-----------------------------------------------------------------------------------------------------------

串口设置OnInitDialog();

CDialog::OnInitDialog();

 m_ctrlComm.SetCommPort(1);
 m_ctrlComm.SetInputMode(1);//二进制

 m_ctrlComm.SetInBufferSize(1024);
 m_ctrlComm.SetOutBufferSize(512);

 m_ctrlComm.SetSettings("9600,n,8,1");

 if(!m_ctrlComm.GetPortOpen())
  m_ctrlComm.SetPortOpen(true);

 m_ctrlComm.SetRThreshold(1);
 m_ctrlComm.SetInputLen(0);
 m_ctrlComm.GetInput();

//OnInitDialog();

//oncomm() 发生通讯事件,主要是从串口接收数据并显示在编辑框中,MSComm事件

file://已经包括好,无须用户自定义消息.

void CSCommTestDlg::OnOnCommMscomm2()
{
 VARIANT variant_inp;
 COleSafeArray safearray_inp;
 LONG len,k;

 BYTE rxdata[2048];
 CString strtemp;

 if(m_ctrlComm.GetCommEvent()==2)
 {
  variant_inp=m_ctrlComm.GetInput();
  safearray_inp=variant_inp;

  len=safearray_inp.GetOneDimSize();

   for(k=0;k<len;k++)
   {
    BYTE bt=*(char *)(rxdata+k);
    strtemp.Format("%c",bt);
    m_edit2+=strtemp;
   }
 }

 

//发数据

void CSCommTestDlg::OnButton1()
{
 file://AfxMessageBox("okok");
 UpdateData(true);
 m_ctrlComm.SetOutput(COleVariant(m_edit3));
}

 

 

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

8.13

之前电脑中毒,决定重装,在C盘,准备格式D盘。

今天学了一下串口

已及一些控件类,

combo,

setcursel()初始当前项

getcursel()当前项的INDEX

setLBTEXT(N,M)获得第N项,写入M数组里面。

 

 

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

8.14

控件EDIT里面要实现垂直分屏或者叫换行,可以在属性那里选多行就有垂直滚动的选项.

现在开始学动态连接库DLL.

 

一个用于WINDOWS应用程序开发的工具是在VC98的DUMPBIN

 

 

(1)DLL 的编制与具体的编程语言及编译器无关

  只要遵循约定的DLL接口规范和调用方式,用各种语言编写的DLL都可以相互调用。譬如Windows提供的系统DLL(其中包括了Windows的API),在任何开发环境中都能被调用,不在乎其是Visual Basic、Visual C++还是Delphi。

(2)动态链接库随处可见

  我们在Windows目录下的system32文件夹中会看到kernel32.dll、user32.dll和gdi32.dll,windows的大多数API都包含在这些DLL中。kernel32.dll中的函数主要处理内存管理和进程调度;user32.dll中的函数主要控制用户界面;gdi32.dll中的函数则负责图形方面的操作。

(3)VC动态链接库的分类

  Visual C++支持三种DLL,它们分别是Non-MFC DLL(非MFC动态库)、MFC Regular DLL(MFC规则DLL)、MFC Extension DLL(MFC扩展DLL)。

  非MFC动态库不采用MFC类库结构,其导出函数为标准的C接口,能被非MFC或MFC编写的应用程序所调用;MFC规则DLL 包含一个继承自CWinApp的类,但其无消息循环;MFC扩展DLL采用MFC的动态链接版本创建,它只能被用MFC类库所编写的应用程序所调用。

  当DLL中的函数改变后,只要不是参数的改变
调用起的函数并不需要重新编译。

http://mmchome.blog.com.cn/archives/2007/2321762.shtml

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

8.15

 

(1)使用extern "C"修饰函数声明,否则,生成的DLL只能供C++调用;

  (2)使用__stdcall修饰函数声明及定义,__stdcall是Windows API的函数调用方式。

 

测试

--------------------------------------------------------------------

#include <stdio.h>
#include <windows.h>

typedef int(*lpAddFun)(int, int); file://宏定义函数指针类型
int main(int argc, char *argv[])
{
HINSTANCE hDll; file://DLL句柄
lpAddFun addFun; file://函数指针
hDll = LoadLibrary("..\\Debug\\dllTest.dll");
if (hDll != NULL)
{
addFun = (lpAddFun)GetProcAddress(hDll, "add");
if (addFun != NULL)
{
int result = addFun(2, 3);
printf("%d", result);
getchar();
}
FreeLibrary(hDll);
}
return 0;
}

 

-----------------------------------------------------------------------

//lib.cpp

#include "lib.h"
int add(int x, int y)
{
return x + y;
}

--------------------------------------------------------------------------

file://.h

#ifndef LIB_H
#define LIB_H
extern "C" int __declspec(dllexport)add(int x, int y);
#endif


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

8.16

1,c要大写

2,应用MFC DLL扩展要加#include   "stdafx.h"   预处理,不然就在SETTING设置

 

终于调用简单例子

首先路径,..那个是EXE和DLL一起的,

然后设置一个EXE对应的MFC EXTERN DLL

H和CPP文件,CPP文件要带预处理

 

在应用程序里面,函数先声明,然后获得地址等,简单的DLL就可以被调用了.

typedef int(*lpAddFun)(int, int);
 
 CString str;


 HINSTANCE hDll;//DLL句柄
 lpAddFun addFun;//函数指针

 hDll = LoadLibrary("..\\Debug\\comDll.dll");

 AfxMessageBox("fsadfasd");

 if (hDll != NULL)
 {
 addFun = (lpAddFun)GetProcAddress(hDll, "add");
 if (addFun != NULL)
 {
  AfxMessageBox("fsadfasd");
 int result = addFun(2, 3);

 str.Format("%d",result);
 
 AfxMessageBox(str);
 AfxMessageBox("1");
 
 }
 FreeLibrary(hDll);
 }

 

注意DLL的H和CPP文件要同时修改,否则接收为NULL.

 

资源拖到另一个工程

1,打开fileview,点击右键-〉add   file   to   project->把那个*.res添加进来,、  
  然后打开resourceview,拖动一个dialog中的dlg到另一个dialog中,  
  最后,从fileview中,吧那个*.res删除,记得不要存盘阿

2,在新的工程里打开旧工程的res文件,然后把你的对话框资源,拖拉到你新工程resource view下的dialog下

 

CreateFile

对该函数理解:首先返回一句柄,然后用该句柄执行一系列初始化函数.

 

串口相关函数:SetupComm()

所属分类:VC/MFC 基础类
-----------------------------------------

在书上看到一个设置串口输入输出缓冲区大小的函数:
SetupComm(hCom,1024,521),
我对串口的输入和输出缓冲区这样的概念不是很理解,有高手能解释一下吗?
还有,为什么输入与输出缓冲区设置的大小不一样呢?这有什么关系吗?

----------------------------------------------------------------------

缓冲区就是在你来不及处理数据的时候暂时保留数据的一块内存,其大小应该根据你的数据传输速率和处理数据的能力大小来设置。如果一直来不及处理数据,又没有合适的纠错方法,就会导致数据丢失。

至于大小不一样,没什么道理,你也可以设置成一样。
-----------------------------------------------------------------------------------------
 
用DCB前先
GetCommState(hCom,&dcb);

 

/***************************cpp

#include "stdafx.h"
#include "lib.h"


int add(int x)
{
  file://CreateFile
 switch(x)
 {
 case 0:
  x=1;break;
 case 1:
  x=2;break;
 case 2:
  x=3;break;
 case 3:
  x=4;break; 
 case 4:
  x=5;break;
 default : ;


 }
  
return x;
}

bool ComOpen(int x)

 CString str;

 switch(x)
 {
 case 0:
  str="COM1";break;
 case 1:
  str="COM2";break;
 case 2:
  str="COM3";break;
 case 3:
  str="COM4";break; 
 case 4:
  str="COM5";break;
 default : ;
 }

 HANDLE m_hCom;

 m_hCom = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL );


 if(m_hCom==(HANDLE)-1)
 {
 AfxMessageBox("打开COM失败!");
 return FALSE;
 }


file://设置com
 DCB dcb;
 GetCommState(m_hCom,&dcb);
 CString s1;
 s1.Format("%d",dcb.StopBits);

 AfxMessageBox(s1);

dcb.BaudRate = 9600; file://波特率为9600
dcb.ByteSize = 8; file://数据位数为8位
dcb.Parity = NOPARITY; file://偶校验
dcb.StopBits = 2; file://两个停止位

if (!SetCommState(m_hCom, &dcb))
{
AfxMessageBox("串口设置出错1!");
}
else
{
AfxMessageBox("成功了!");
}


dcb.fBinary = TRUE;
dcb.fParity = TRUE;

COMMTIMEOUTS TimeOuts;


file://设定读超时
 TimeOuts.ReadIntervalTimeout=MAXDWORD;
 TimeOuts.ReadTotalTimeoutMultiplier=0;
 TimeOuts.ReadTotalTimeoutConstant=0;
file://在读一次输入缓冲区的内容后读操作就立即返回,
file://而不管是否读入了要求的字符。

 file://设定写超时
TimeOuts.WriteTotalTimeoutMultiplier=100;
TimeOuts.WriteTotalTimeoutConstant=500;
SetCommTimeouts(m_hCom,&TimeOuts); file://设置超时

SetupComm(m_hCom, 1024, 1024);
PurgeComm(m_hCom,PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);


if (!SetCommState(m_hCom, &dcb))
{
AfxMessageBox("串口设置出错2!");
}

file://SetupComm(m_hCom, 1024, 1024);
file://PurgeComm(m_hCom,PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);

 return true;
}


bool GetComData(int x)
{
 return true;
}

/*********************************button

HINSTANCE hDll;//DLL句柄
 lpAddFun addFun;//函数指针
 CString str;

 hDll = LoadLibrary("..\\comDll\\Debug\\comDll.dll");

 

 if (hDll != NULL)
 {
 addFun = (lpAddFun)GetProcAddress(hDll, "ComOpen");


 if (addFun != NULL)
 {
 
 addFun(m_combo1.GetCurSel()) ;
 
 
 }

 else
   AfxMessageBox("为NULL,请检查CPP文件");
 FreeLibrary(hDll);
 } 

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

8.17

使用CEdit的CString方法

CString   yourstring;  
  GetDlgItemText(IDC_YOUREDIT,yourstring);  
  这样就把CEdit的值放到字符串里了。   

 

如何解决变量在不同函数不一致问题

注意返回值
 

 


BOOL WriteFile(
HANDLE hFile, // handle to file to write to
LPCVOID lpBuffer, // pointer to data to write to file
DWORD nNumberOfBytesToWrite, // number of bytes to write
LPDWORD lpNumberOfBytesWritten, // pointer to number of bytes written
LPOVERLAPPED lpOverlapped // pointer to structure for overlapped I/O
);

lpBuffer应该就是字符首指针
其中nNumberOfBytesToWrite是你要发送的字节数;
lpNumberOfBytesWritten是实际发送出去的字节数;他是一个指针,用来保存writefile函数实际发送的字节数。

 

-----------------------------------------------------------数据转换问题

CString和_variant_t

CString=(( char *)( _bstr_t )  _variant_t);

int m CString s

   m=atoi(s.GetBufferSetLength(255));  

BYTE转换为CString

for(k=0;k<len;k++)
   {
    BYTE bt=*(char *)(rxdata+k);
    strtemp.Format("%c",bt);
    str+=strtemp;
   
   }

BYTE   key[]   =   {'A','B','C','\0'};  
  CString   str;  
  str.Format("%s",key);   
    

CString   str   =   "ABC";  
  BYTE   key[5]   =   {0};  
  for(int   i   =0;   i   <   str.GetLength();   i++)  
  {  
  key[0]   =   str.GetAt(i);  
  }

 

 BYTE *cByte=(BYTE   *)c.GetBuffer(0);

-----------------------------------------------------------------------------------------------------------

HANDLE   hFile   =   CreateFile("c:\\test.txt",GENERIC_READ,FILE_SHARE_WRITE,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);  
  DWORD   dwCount;  
  SetFilePointer(hFile,   NULL,   NULL,   FILE_BEGIN);  
  BYTE   szStore[128];  
  DWORD   dwReadCount   =   128;  
  DWORD   dwWriteCount   =   0;  
  while(dwReadCount==128)  
  {  
  ReadFile(hFile,   szStore,   128,   &dwReadCount,   NULL);  
  WriteFile(hWriteFile,szStore,dwReadCount,   &dwWriteCount,   NULL);  
  }   
   

 

-------------------------------------------------------------------------------------------------------------

BYTE *cByte=(BYTE   *)c.GetBuffer(0);


DWORD   dwReadCount   =   128;  
DWORD   dwWriteCount   =   0;  
 CString s;

while(dwReadCount==128)  
  {  
 s.Format("%d",dwReadCount);
   AfxMessageBox(s);

  ReadFile(m_hCom, cByte,   128,   &dwReadCount,   NULL);  
 s.Format("%d",dwReadCount);
 AfxMessageBox(s);
  WriteFile(m_hCom,cByte,dwReadCount,   &dwWriteCount,   NULL);
 
  s.Format("%d",dwReadCount);
   AfxMessageBox(s);

  }  

//奇怪,dwReadCount的值,

 

--------------------------------------------------------------------------------------------------------------

BYTE *cByte=(BYTE   *)c.GetBuffer(0);
 BYTE   c2[1024];

DWORD   dwReadCount   =   128;  
DWORD   dwWriteCount   =   0;  
 CString s;

 while(dwReadCount==128)  
  {  
// s.Format("%d",dwReadCount);
//   AfxMessageBox(s);

 // ReadFile(m_hCom, cByte,   128,   &dwReadCount,   NULL);  
 
 // WriteFile(m_hCom,cByte,dwReadCount,   &dwWriteCount,   NULL);
 WriteFile(m_hCom,cByte,128,   &dwReadCount,   NULL);

 ReadFile(m_hCom, c2,   128,   &dwReadCount,   NULL);

 s.Format("%s",c2);

 AfxMessageBox(s);

 s.Format("%d",dwReadCount);
 AfxMessageBox(s);

  }  

----------------------------------------------------------------------------------------------------------------
 未解决句柄传送,解决句柄传送

不知道能否解决

            “共享段”内的变量必须进行初始化,你如果不初始化的话,那编译器就会把它们放到默认的数据节中;就拿你的例子来说,编译器看到没有初始化的“BYTE   KeyMap[256]”,就会把它放到默认的数据节中,这样你声明的段“SYSHK”内将没有任何数据,“没有数据的段”编译器是不会产生的,当然会“waning:/SECTION指定的段SYSHK不存在”!  
            你把“BYTE   KeyMap[256]”改成“int   n=0”试试!   

#pragma   data_seg("SYSHK")  
  BYTE   KeyMap[256];  
  #pragma   data_seg()  
  #pragma   comment(   linker,   "/section:SYSHK,rws"   )   
  

 

可行

但有点奇怪

#pragma data_seg("Shared")
   HANDLE handle=NULL;   file://必须在定义的同时进行初始化!!!!
#pragma data_seg()
#pragma   comment(linker, "/section:Shared,rws"   )  
 

--------------------------------------------------------------------------------------------------------------

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

8.19

dll重载两次就有问题,里面句柄会被冲掉.所以出现句柄为空.

CPP里面可以作变量定义

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

8.20

dll函数名解释问题

在DEF

EXPORTS
     //SendDataToCom 这里是CString等类型什么的,反正你觉得dll奇怪就可以这里一试

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

8.21

出现BIND返回为空,应该在CPP文件检查一下SOCKET是否直接副职,改为在OINITDLG或其他地方副职.

 

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

8.22

要用this指本窗口,就需要是类方法才行.

另外WSAAsyncSelect()是在本方法执行完后才开始监听?

全局变量注意多用g开头.

下面的代码在文本框最后追加"abc"      
  int   nLength=m_edit.SendMessage(WM_GETTEXTLENGTH);      
  m_edit.SetSel(nLength,     nLength);      
  m_edit.ReplaceSel("abc");   
 

当然也可以先把编辑框的内容取出来放到CString里,然后把几个CString相加  
  SetWindowText(str+str2..);  
  上面的方法更好些。

------------------------------------------------------------------------

我往多行风格的CEDIT控件填充文本后,可是还是要用滚动条移到底部才能看到文本,  
  当多行风格的文本框获得增加文本后,滚动条还是没有跟随移动到底部,希望给我具体  
  代码参考,实现当文本增加后,滚动条也自动往下移动<注意,CEDIT的文本不是手动输入  
  的,是程序获取的

CString   str;  
  m_edit.GetWindowText(str);  
  m_edit.SetSel(str.GetLength(),   str.GetLength());

easypaper的方法我记得在NT下不管用,我用的方法是  
  m_edit.LineScroll(m_edit.GetLineCount());

 

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

8.23

 m_edit_Ping+=""inet_ntoa(ClientAddr.sin_addr);
获得socket对方IP

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

8.27

#include <icrsint.h> //Include support for VC++ Extensions
#import "C:\Program Files\Common Files\System\ADO\msado15.dll" \
no_namespace rename("EOF", "adoEOF")

注意DLL文件,搜索一下,是否在路径里面.

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

8.28ADO数据库

获得指针,不知道前面有没写到.

CEdit* cEdit;

pEdit=(CEdit*)GetDlgItem(IDC_EDIT2);
 pEdit->GetWindowText(str2); 

好象要添加记录就应该先删除记录,不然就出现盏错误.

处理好记录号是关键

 改记录中字段值 可以将记录指针移动到要修改记录的位置处,直接用PutCollect(字段名,值)将新值写入并Update()更新数据库既可。

 m_list_Ping.ResetContent();可以清空Clistbox

m_pRecordset要比m_pConnection先撤消,而且在用close之前,要先检查两指针是否都实例化了.

 

ODBC

基于DLL结构,odbc32.dll,定义了应用程序编程接口,借助注册表.

odbc三个重要元素:环境,连接,语句.

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

9.3

事实上,Open()函数在构造SELECT语句时,会把m_strFilter和m_strSort的内容放入SELECT语句的WHERE和ORDER BY子句中。如果在Open的lpszSQL参数中已包括了WHERE和ORDER BY子句,那么m_strFilter和m_strSort必需为空。

 

  • CFieldExchange 程, RFX 制。
  • CDBException 理。 息。
  • ==================================================
  • 9.4

    灰度图像滤波去噪的目的是去除灰度指纹图
    像中的叉连、断点及模糊不清的部分.


    灰度图像滤波去噪的目的是去除灰度指纹图
    像中的叉连、断点及模糊不清的部分.五个基本步骤完成.

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

    9.5

    ODBC数据添加用AddNew()

    之后用

    m_pSet->Update();

     

    修改用

     m_pSet->Edit();

    再在函数或者消息那里用

    UpdateData(true);
     m_pSet->Update();就OK

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

    9.6

    捕捉异常要记得在关键代码捕捉,否则就用F9跟踪一下,是否代码块不在捕捉异常之列.

    指纹匹配的方法很多,包括基于奇异点的匹配、嵴模式的匹配、特征点的匹配、特征点线对(两个特征点的连线)匹配,以及特征点组的匹配方法。

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

    MFC_ODBC\n\nMFC_OD\n\n\nMFCODBC.Document\nMFC_OD Document

    9.7

    在String Table

    的字串表修改IDR_MAINFRAME的标题

    在initlnstance()里面

    m_pMainWnd->SetWindowText("数据库");改标题更好

    使控件变灰

    GetDlgItem(IDC_BUTTON1)->EnableWindow(FALSE);

    CEdit获得焦点

    pCtrl=(CEdit *)GetDlgItem(IDC_ID);
     pCtrl->SetFocus();

    修改STATIC文本颜色,添加CtlColor

    if(pWnd->GetDlgCtrlID()==IDC_STATIC1)
     {  
     //pDC->SetBkColor(RGB(0,128,128));  
    // pDC->SetBkColor(RGB(32,200,200));  
    // pDC->SetTextColor(RGB(128,0,0));  
       
     }  

     

     m_pSet->Edit();
     m_pSet->m_name=str;
     m_pSet->Update();

    修改数据

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

    9.10

    moveLast并未能触发isEof,??

    在void CMFC_ODBCView::OnInitialUpdate()

    可以进行一些初始化操作

    GetRecordCount数据库内剩余记录个数

     

    while(!m_pSet->IsEOF(   ))  
       
      m_pSet->MoveNext(   );  
       
      调用GetRecordCound可获得记录集中的记录总数,该函数的声明为  
       
      long   GetRecordCount(   )   const;  
      要注意这个函数返回的实际上是用户在记录集中滚动的最远距离.要想真正返回记录总数,只有调用MoveNext移动到记录集的末尾(MoveLast不行).

     m_pusrrcdset->m_pDatabase->ExecuteSQL可以执行SQL语句.

    使用delete后,指针指向一个无效的随机的位置,通常用movenext应该没问题,但movenext之后也不会是下一条记录,所以应该requery,if(!Eof)delete。 

    如果调用AddNew()方法,则只能添加在纪录集末尾。

    除非你把那个纪录以后的所有记录都delete,加入这条记录,再把他们都加进来

    ***********查询是否还有记录************************************

    while(!m_pSet->IsEOF( ))
      {
      count++;
      m_pSet->MoveNext(   ); 
      }

    if((count-1)==0)我采用这一方法,因为Delete后指针都不知道只指向哪里去了.

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

    9.12

    GetDlgItem(IDC_NextRecord)->EnableWindow(false);使窗口冻结

    WaitCommEvent是阻塞的,通常的做法是开一个线程   循环调用WaitCommEvent(),中间判断如果符合条件,发消息给主线程。  

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

    9.13

    SetCommMask (handle, EV_RXCHAR);写事件

     if(WaitCommEvent( handle,   &dwCommStatus,   NULL   )!=0)
      AfxMessageBox("ok");

      if   ((dwCommStatus & EV_RXCHAR) == EV_RXCHAR)//

     

    char *_itoa( int value, char *string, int radix ); _itoa 转换

    str.Format(_T("%02x %02x %02x %02x %02x %02x %02x %02x") , cByte[0] , cByte[1] , cByte[2] , cByte[3] , cByte[4] , cByte[5] , cByte[6] , cByte[7]);解决数组转换问题

    BYTE cByte[8] = {0};
     cByte[0] = 0x1b;
     cByte[1] = 0x72;
     cByte[2] = 0x73;
     cByte[3] = 0x00;
     cByte[4] = 0x03;
     cByte[5] = 0x83;
     cByte[6] = 0x00;
     cByte[7] = 0x86;

     char* Buffer;
     Buffer = (char*)malloc(8*sizeof(BYTE));
     CString strByte;
     for (int i=0;i < 8;i++)
     {
      itoa(cByte[i],Buffer,16);
      strByte += Buffer;
      strByte += ' ';
     }
     AfxMessageBox(strByte);
     free(Buffer);

    PurgeComm(   handle,PURGE_RXCLEAR);清空输入缓冲区

     

    定义WSAOVERLAPPED ol;
    WaitCommEvent(m_handle_1,&dwEvtMask,&ol);

     

    EV_RXFLAG: 接收到事件字符(DCB结构中EvtChar成员),放入输入缓冲区。 

     if   ((dwCommStatus & EV_RXFLAG) == EV_RXFLAG)//

     

    EV_BREAK 检测到输入为止

    EV_CTS CTS(清除发送)信号改变状态

    EV_DSR DSR(数据设置就绪)信号改变状态

    EV_ERR 发生了线路状态错误.

    线路状态错误为:

    CE_FRAME(帧错误)

    CE_OVERRUN(接收缓冲区超限)

    CE_RXPARITY(奇偶校验错误)

    EV_RING 检测到振铃

    EV_RLSD RLSD(接收线路信号检测)信号改变状态

    EV_EXCHAR 接收到一个字符,并放入输入缓冲区

    EV_RXFLAG 接收到事件字符(DCB成员的EvtChar成员),度放入输入缓冲区

    EV_TXEMPTY 输出缓冲区中最后一个字符发送出去

    ClearCommError 查缓冲区

    EV_TXEMPTY后用EV_RXCHAR可以完成按抬手指工作.

    涉及cfiledialog

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

    9.14

    eXeScope  
      Resource   Hacker   可能可以提取DLL资源

    如果没有压缩过的话.
    打开VS6.0, 文件\打开,
    文件类型: 所有
    方式: resource

    然后另存为rc文件就可以提取里面的

     

    CString a="01 2d f4 a6 8e"转换为十进制????

    CString a="01 2d f4 a6 8e";
     int aa[5];
     memset(aa,0,sizeof(aa));
     sscanf(a,"%x %x %x %x %x %x",&aa[0],&aa[1],&aa[2],&aa[3],&aa[4]);

    最简单的使用CFileDialog方式

    CFileDialog   fileDlg(true); 
     fileDlg.DoModal();

    dll里面创建对话框先插入资源,然后NEW CLASS,不过有个比较奇怪的问题,可以先//再删除注释.记得在资源.h,是资源.h里面添加#include "resource.h"才可以解决

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

     9.15

    1。设置字体大小  
      CreateFont()   //   在里面设置大小  
      HFONT   CreateFont(  
          int   nHeight,                               //   height   of   font  
          int   nWidth,                                 //   average   character   width  
          int   nEscapement,                       //   angle   of   escapement  
          int   nOrientation,                     //   base-line   orientation   angle  
          int   fnWeight,                             //   font   weight  
          DWORD   fdwItalic,                       //   italic   attribute   option  
          DWORD   fdwUnderline,                 //   underline   attribute   option  
          DWORD   fdwStrikeOut,                 //   strikeout   attribute   option  
          DWORD   fdwCharSet,                     //   character   set   identifier  
          DWORD   fdwOutputPrecision,     //   output   precision  
          DWORD   fdwClipPrecision,         //   clipping   precision  
          DWORD   fdwQuality,                     //   output   quality  
          DWORD   fdwPitchAndFamily,       //   pitch   and   family  
          LPCTSTR   lpszFace                       //   typeface   name  
      );  
       
      SelectObject()   //选进去  
      然后再写上去  
       
      2   旋转角     //不知道~  
       
      3   是指最简单应用程序窗口,像记事本窗口那样的)上的;  
      ---     他是设置了很多全局变量来保存字体信息而已~  
       
      4   哪个函数是可以将变量值输出到当前窗口上的;  
        先获得DC,在OnDraw()里写下面的话  
            CString   s;  
            wsprintf(s,"%d",m_nTest);     //m_nTest是你所说的变量  
            pDC->TextOut(x,y,s);  
       
      5   如何解决在画两个圆相交时,后画上去的圆总会复盖掉先画的一部分,我用的是Ellipse();  
       
            看一下光栅操作,如果你直接画,本来就是复盖的~  
       
      6   关于COLORREF  
      :the   COLORREF   value   has   the   following   hexadecimal   form:    
      0x00bbggrr     //注意这个就行了   ,一般用   RGB(255,255,0);  
       
      7   应该怎样定义,调用这些函数是否要哪些头文件,我写时总是提示错误,请说明一下,谢谢!!  
       
      --      
      LOGBRUSH   logBrush;  
      logBrush.lbStyle   =   BS_SOLID;  
      logBrush.lbColor   =   RGB(0,255,0);  
      CPen   myPen(PS_DOT|PS_GEOMETRIC|PS_ENDCAP_ROUND,   2,   &logBrush);//这样就OK了

     

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

    9.17

    多线程问题

    如果涉及资源比较多,对话框之类难以实现,就尽量不用CreateThread,因为该函数有可能导致主窗口句柄为空不一至,而出现ASSERT错误.

     hThread=CreateThread(NULL,0,
    (LPTHREAD_START_ROUTINE)ThreadFunc,AfxGetMainWnd()->m_hWnd,0,&ThreadID);

    这时候可以选择用AfxBeginThread

    不过注意的是起线程序函数记得要带UINT ThreadFunc(LPVOID pParam)//LPVOID参数

    而且在声明的H中用static防止返回this指针.

    static UINT ThreadFunc(LPVOID pParam);

    不然就会出现

    error C2665: 'AfxBeginThread' : none of the 2 overloads can convert parameter 1 from type 'unsigned int (__cdecl *)(void)'

    改用循环对比字符串来实现,不用事件,事件有些问题***************

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

    9.18

    // 设置要打开的文件
    char* pszFileName = "c:\\test.dat";

    CFile myFile;
    CFileException fileException;

    // 打开文件,中间可能会出现异常
    int iOpenResult = myFile.Open(pszFileName,
        CFile::modeCreate 
    | CFile::modeReadWrite,
        
    &fileException);

    if(!iOpenResult)
    {
        
    // 如果出错,输出出错信息
        TCHAR szError[1024];
        fileException.GetErrorMessage(szError, 
    1024);
        cout 
    << szError << endl;
        myFile.Close();
    }

    else
    {
        
    // 向文件写入数据
        char szWrite[1024];
        strcpy(szWrite, 
    "I am xuzhong , I love this launguage .\n");
        myFile.Write(szWrite, lstrlen(szWrite));
        myFile.Close();
    }

    CFileDialog mFileDlg(false,"*.miu","",OFN_HIDEREADONLY,
     "所有文件|*.*|miu文件|*.miu||");
     mFileDlg.DoModal();

     设置全局变量中的是一个方法是在一个.CPP内声明

    然后在另一个要用到的类.CPP里 extern

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

    9.19

    传过去都都变为一个字符,空格也为一字符,总共453个,文件都是字符串形式

    strtoul(temp, NULL, 16) ;字符串转16进制

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

    9.20

    DLL和对话框多线程窗口句柄处理问题,两方面各设置一多线程,用全局变量传递消息.

    GetActiveWindow(),获取当前线程负责处理消息的窗口

    GetForegroundWindow(), 获取全局的输入焦点窗口。就是你键入的字符出现在的那个窗口。

     

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

    9.23

    设置字体,CFont对象用完要记得销毁

     CFont   txtFont;  
       
     txtFont.CreatePointFont(15,"宋体");  
     SetFont(&txtFont);  
     DeleteObject(SelectObject(*GetDC(),txtFont)); 

     

    响应WM_CTLCOLOR消息:  
      HBRUSH   CMyDlg::OnCtlColor(CDC*   pDC,   CWnd*   pWnd,   UINT   nCtlColor)    
      {  
       
       
      switch   (nCtlColor)  
      {        
      case   CTLCOLOR_STATIC:  
      pDC->SetTextColor(RGB(0,   0,   0));  
      pDC->SetBkColor(RGB(255,255,255));  
      case   CTLCOLOR_EDIT:  
      pDC->SetTextColor(RGB(0,   0,   0));//这就是改变编辑框字体颜色  
      pDC->SetBkColor(RGB(255,255,255));//这是改变编辑框背景的颜色  
      case   CTLCOLOR_LISTBOX:  
      pDC->SetTextColor(RGB(0,   0,   0));  
      pDC->SetBkColor(RGB(255,255,255));  
      case   CTLCOLOR_SCROLLBAR:  
      pDC->SetTextColor(RGB(0,   0,   0));  
      pDC->SetBkColor(RGB(255,255,255));  
      case   CTLCOLOR_BTN:  
      pDC->SetTextColor(RGB(0,   0,   0));  
      pDC->SetBkColor(RGB(255,255,255));  
      case   CTLCOLOR_DLG:          
      return   m_Brush;  
      }  
       
      //   TODO:   Return   a   different   brush   if   the   default   is   not   desired  
      return   m_Brush;  
      }

     

     if   (pWnd->GetDlgCtrlID()   ==   IDC_EDIT_TO)  
      {  
                  //   Set   the   text   color   to   red  
                  pDC->SetTextColor(RGB(255,   0,   0));  
       
                  //   Set   the   background   mode   for   text   to   transparent    
                  //   so   background   will   show   thru.  
                  pDC->SetBkMode(TRANSPARENT);  
       
      }

    注意,如果是被禁用的控件就另外用其他方法设置,因为禁用后GetDlgCtrlID!=控件名.

    设置字体大小

    CClientDC   dc(this);  
       
     CEdit*   pEdit   =   (CEdit*)GetDlgItem(IDC_EDIT1);  
       
     CFont*   font   =   new   CFont;  
     font->CreatePointFont(150,   _T("华文行楷"),   &dc);  
       
     if(pEdit)  
     {  
     pEdit->SetFont(font,   TRUE);  
     }  
     else  
     AfxMessageBox("Failed");  

     

    关于CStatic ,要设置BN_CLICKED消息,还必须设置属性为通知(Notify)

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

    9.26

    不必要绑定到单文档

    #include   "afxdb.h"

    CDatabase   db;  
     db.OpenEx( _T( "DSN=table1" ),CDatabase::noOdbcDialog);   //连上数据源

     CRecordset   rs(&db);  
     rs.Open(AFX_DB_USE_DEFAULT_TYPE,"select   *   From   table1");  

    //获得指针方便行事
      int   nfieldcount=rs.GetODBCFieldCount();  
      CString   msg;  
      msg.Format("There   are   %d   fields   in   table1",nfieldcount);  
      AfxMessageBox(msg);  
      //field   0   is   int   field,name   "intfield",retrieve   by   field   index  
      CDBVariant   dbvar;  
      rs.GetFieldValue((short)0,dbvar);  
      //field   1   is   string   field,name   "strfield",retrieve   by   field   name  
      CString   dbstrvar;  
      rs.GetFieldValue("strfield",dbstrvar);  
      msg.Format("field   0   value:%d,field   name   strfield   value=%s",dbvar.m_iVal,dbstrvar);  
      AfxMessageBox(msg);  
      rs.Close();   
      db.Close();

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

    9.27

    学习Clistctrl的焦点设置问题

    光用SetItemState(lpLIST,LVIS_SELECTED|LVIS_FOCUSED,LVIS_FOCUSED|LVIS_SELECTED);

    是不行的,下次要指向另外一个选项的话,那么就先设置.SetFocus

     

    int CMFC_NewOdbcDlg::GetCursel()//焦点行提取函数
    {
     if(m_lIdAndName.GetSelectedCount()<=0)//先判断是否有焦点触发
      return -1;

     for(int i=0;i<m_lIdAndName.GetItemCount();i++)//焦点触发后
     {
      if(m_lIdAndName.GetItemState(i,LVIS_SELECTED)==LVIS_SELECTED)
      {
       return i;
      }
     }
     return 1;
    }

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

    10.6

    CRecordset::IsEOF

    BOOL IsEOF( ) const;

    Return Value

    Nonzero if the recordset contains no records or if you have scrolled beyond the last record; otherwise 0.

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

     10.9

    CListCtrl

    EnsureVisible(lpLIST,false);可以滚动滚动条,随着lpLIST而滚动.

    多线程

    AfxBeginThread(SendData,this,THREAD_PRIORITY_NORMAL);   //调用  
      UINT   SendData(LPVOID   pParam)  
      {  
            CTestThreadDlg   *dlg   =   (CTestThreadDlg*)pParam;  
            dlg->m_a   =   0;         //不就可以了吗?关键是把对话框的指针传过来在进行强制转化!  
            return   0;  
      }  

     

    如果出现

    TRACE1("Error: no data exchange control with ID 0x%04X.\n", nIDC);错误

    可以先REBUILD ALL也就是中文版的全部重建

    之后应该有冲突的ID出现,删除!

    原因是你之前的控件建立了映射,而只删除控件没删除映射.

    关于Clistctrl的REPORT属性用法,点击不了整行

    可以

    CListCtrl   *   p_ListCtrl= (CListCtrl *)GetDlgItem(IDCidAndname);  
     p_ListCtrl->SetExtendedStyle(LVS_EX_FULLROWSELECT);

    这个是设置list选中时整行选中.

    strlen计算字符串里有多少字符

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

    10.11

    Requery 方法通过重新发布原始命令和再次检索数据来刷新数据源中 Recordset 对象的所有内容。调用此方法等价于依次连续调用 CloseOpen 方法。如果正在编辑当前记录或正在添加新记录,将发生错误。

    Recordset 对象打开时,定义游标性质(CursorTypeLockTypeMaxRecords 等)的属性为只读。因此,Requery 方法只能刷新当前游标。要更改任何一个游标属性并查看结果,必须使用 Close 方法以使这些属性重新变为读/写。然后可以更改属性设置并调用 Open 方法重新打开游标。

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

    10.12

    请问一下Access数据库文本长度怎么修改?

    把字段类型改为备注型
     
    关于设备读取得286字节,是因为最后一个字符和前86 00两个字符没读取,导致292-3*2=286
     
    catch(CDBException *e)如果是catch(CDBException )
    则捕捉不了异常
     
    access是否格式只接受01字符.
     
    强制转换CString 为char *
    gStr =(LPTSTR)(LPCTSTR)str ;
     
    ====================================================
    10.13
    void CTest2DllDlg::OnButton1()
    {
     HINSTANCE hDll;
    }

    HINSTANCE hDll;
    void CTest2DllDlg::OnButton1()
    {
    }
    句柄不一样
    第一个不为空,0xcccccccc
    第二个为空
    NTDLL! 7c921230()
    的处理出现在DLL
    结果解决办法是尽量不用全局变量
     
    关于第二次依旧出现DLL那个问题,在原程查看CString,改为局部变量......
    ======================================================
    10.14
    Single-Threaded                    单线程静态链接库(release版本)
    Multithreaded                      多线程静态链接库(release版本)
    multithreaded DLL                  多线程动态链接库(release版本)  
    Debug Single-Threaded              单线程静态链接库(debug版本)
    Debug Multithreaded                多线程静态链接库(debug版本)
    Debug Multithreaded DLL            多线程动态链接库(debug版本)

    单线程: 不需要多线程调用时, 多用在DOS环境下
    多线程: 可以并发运行
    静态库: 直接将库与程序Link, 可以脱离MFC库运行
    动态库: 需要相应的DLL动态库, 程序才能运行
    release版本: 正式发布时使用
    debug版本: 调试阶段使用   

     

    两个都为共享就出现那问题NTDLL! 7c921230()

    原来是你的工程设置得有问题,你的DLL输出的类中包含了string类子对象,它也需要用标准dll接口的方式输出,这可以通过在project-->settings-->c/c++标签页中的category下拉筐中选code generation,然后在Use Rutime Library中选DEBUG Multithreaded DLL或Mutithreaded DLL来做到,但你的却是DEBUG single thread。

    解决办法:主工程和DLL工程的都设置为同样的DEBUG Multithreaded DLL或Mutithreaded DLL。

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

    10.15

    编辑标签应该可以修改Clistctrl的第一列数据.

    身份证前六位是行政区划号码,后八位是出生年月日,后三位是顺序编号,顺序编号的最后一位单数为男性,偶数为女性。最后一位是校验码,是用特定公式校验前十七位号码得出的0-9位的数字,如校验结果为10,则校验码为X。

    身份证号有18位数字。排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。
    假设身份证号为: ABCDEF GHIJKLMN OPQ R
    1.AB表示身份证号持有人所在的省,CD是市,EF是县。一般用自己的就行,也可以稍微改改。
    2.GHIJKLMN是出生年月日,如19780328。像一楼写的16890214,肯定是假的。
    3.后四位数,有计算公式,但一般不会去算,随便蒙就行,一般看不出来,电脑也没有库。注意Q这位数,男的是奇数,女的是偶数。

     各省市地区国家代码前两位代码是:
    北京 11 吉林 22 福建 35 广东 44 云南 53 天津 12 黑龙江 23 江西 36 广西 45 西藏 54 河北 13 上海 31 山东 37 海南 46 陕西 61 山西 14 江苏 32 河南 41 重庆 50 甘肃 62 内蒙古 15 浙江 33 湖北 42 四川 51 青海 63 辽宁 21 安徽 34 湖南 43 贵州 52 宁夏 64 新疆 65 台湾 71 香港 81 澳门 82 国外 91

     

    第十八位数字的计算方法为:
    1.将前面的身份证号码17位数分别乘以不同的系数。从第一位到第十七位的系数分别为:7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2
    2.将这17位数字和系数相乘的结果相加。
    3.用加出来和除以11,看余数是多少?
    4余数只可能有0 1 2 3 4 5 6 7 8 9 10这11个数字。其分别对应的最后一位身份证的号码为1 0 X 9 8 7 6 5 4 3 2。
    5.通过上面得知如果余数是2,就会在身份证的第18位数字上出现罗马数字的Ⅹ。如果余数是10,身份证的最后一位号码就是2。

    例如:某男性的身份证号码是34052419800101001X。我们要看看这个身份证是不是合法的身份证。
    首先:我们得出,前17位的乘积和是189
    然后:用189除以11得出的结果是17 + 2/11,也就是说余数是2。
    最后:通过对应规则就可以知道余数2对应的数字是x。所以,这是一个合格的身份证号码。

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

    10.16

    memset与memcpy用法,及作用  

    memset:作用是在一段内存块中填充某个给定的值,它对较大的结构体或数组进行清零操作的一种最快方法。

    memcpy:作用是把一块内存中的字节,不管其中的内容是什么,从内存的一个区域复制到另一个区域。

    Mid   语句来得到某个字符串中的几个字符。  

    Dim   MyString,   FirstWord,   LastWord,   MidWords  
      MyString   =   "Mid   Function   Demo"       建立一个字符串。  
      FirstWord   =   Mid(MyString,   1,   3)       '   返回   "Mid"。  
      LastWord   =   Mid(MyString,   14,   4)       '   返回   "Demo"。  
      MidWords   =   Mid(MyString,   5)       '   返回   "Funcion   Demo"。  

     

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

    10.17

    向串口发大量16进制数可以换种思维

    先将特征两个转为一个byte,然后利用数组,传过去.

     

    自己写的CString转为16进制的函数

    byte CStringTo16byte(CString s)
    {
     byte b16=0,b10=0,all=0;
     CString s16,s10;

     s16=s.Mid(0,1);
     s10=s.Mid(1,1);

     if(s16 == "1")
      b16=1;  
     if(s16 == "2")
      b16=2;  
     if(s16 == "3")
      b16=3;  
     if(s16 == "4")
      b16=4;  
     if(s16 == "5")
      b16=5;  
     if(s16 == "6")
      b16=6;  
     if(s16 == "7")
      b16=7;  
     if(s16 == "8")
      b16=8;  
     if(s16 == "9")
      b16=9;  
     if(s16 == "a")
      b16=10;  
     if(s16 == "b")
      b16=11; 
     if(s16 == "c")
      b16=12; 
     if(s16 == "d")
      b16=13; 
     if(s16 == "e")
      b16=14; 
     if(s16 == "f")
      b16=15;
     
     if(s10 == "1")
      b10=1; 
     if(s10 == "2")
      b10=2; 
     if(s10 == "3")
      b10=3; 
     if(s10 == "4")
      b10=4; 
     if(s10 == "5")
      b10=5; 
     if(s10 == "6")
      b10=6; 
     if(s10 == "7")
      b10=7; 
     if(s10 == "8")
      b10=8; 
     if(s10 == "9")
      b10=9; 
     if(s10 == "a")
      b10=10;  
     if(s16 == "b")
      b10=11; 
     if(s10 == "c")
      b10=12; 
     if(s10 == "d")
      b10=13; 
     if(s10 == "e")
      b10=14; 
     if(s10 == "f")
      b10=15;

     all=b16*16+b10;
     s16.Format("%d",all);
     AfxMessageBox(s16);

     return all;
    }

    另外用 all[0]=0x00;相加即可以得到16进制的byte

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

    10.18

    计算两个摸版的时候注意校验和和总和.

    byte只存两位

    如byte b=0x1234

    其存储为0x34

    突然断电,此之前刚刚保存了一下,但是来电后我的工作区就打不开了

    把dsw、dsp、clw等文件都删掉,用vc新建工程,把源文件加入工程后,重建clw就行了

    删掉原来的.clw。  
      回到VC里,按Ctrl_W,弹出一对话框。按Add   All按钮。  
      就生成了。

     

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

    10.22

    hbr = (HBRUSH) ::CreateSolidBrush(RGB(240, 255, 240)); 改变颜色的另一重要参数

    对于部分控件

     m_lIdAndName.SetBkColor(RGB(1,100,250));

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

    10.24

     system("cmd");可以调用系统cmd

    调用该控件的IsWindowVisible()成员函数,真时表示SW_SHOW假时表示SW_HIDE。

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

    10.25

    CDatabase m_database;
     CString sDriver = "MICROSOFT ACCESS DRIVER (*.mdb)"; //数据库驱动程序的类型
     CString strPath="D:\\Myfile.mdb";
     CString sDsn;                                      
     sDsn.Format("ODBC;DRIVER={%s};DSN='';PWD='';DBQ=%s",sDriver,strPath);
     // Open the database
     if( !m_database.Open(NULL,false,false,sDsn) )
     {
      AfxMessageBox("连接数据库失败!",MB_OK,0);
      return;
     }

    出现数据库不支持动态记录集的话是设置没好.

    CDatabase的Open函数定义如下:  
      virtual   BOOL   Open(   LPCTSTR   lpszDSN,   BOOL   bExclusive   =   FALSE,   BOOL   bReadOnly   =   FALSE,   LPCTSTR   lpszConnect   =   “ODBC;”,   BOOL   bUseCursorLib   =   TRUE   );  
       
      其中bUseCursorLib   参数的msdn解释如下:  
      TRUE   if   you   want   the   ODBC   Cursor   Library   DLL   to   be   loaded.   The   cursor   library   masks   some   functionality   of   the   underlying   ODBC   driver,   effectively   preventing   the   use   of   dynasets   (if   the   driver   supports   them).   The   only   cursors   supported   if   the   cursor   library   is   loaded   are   static   snapshots   and   forward-only   cursors.   The   default   value   is   TRUE.   If   you   plan   to   create   a   recordset   object   directly   from   CRecordset   without   deriving   from   it,   you   should   not   load   the   cursor   library.  
       
      大意是说假如bUseCursorLib为TRUE时,ODBC光标库将被加载。光标库会覆盖ODBC驱动程序的一些功能,有效地阻止动态记录集的使用(假如ODBC驱动程序支持动态记录集的使用的话)。假如光标库被加载唯一的光标支持的是静态快照集和唯一向前的光标。参数默认值是TRUE。假如你直接创建一个CRecordset类对象而不是继承自它,你不应该装载光标库。  
       
            因此问题的解决办法是将bUseCursorLib的值设为FALSE。  

     

    GetCurrentDirectory===================

     DWORD nBufferLength;
     char c[100];
     GetCurrentDirectory(nBufferLength,c);

    不要依赖于GetCurrentDirectory返回目录。获得当前模块所在目录可以用GetModuleFileName和PathRemoveFileSpec。

     

    当前路径不需要\\如"comDll.dll"

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

    10.26

    出现NTDLL运行时错误也有可能是因为DLL返回值不对,不用改为共享DLL.

    隐士连接就是你在你的程序中加入dll的头文件,然后在project->settings->link->object/library   modules里面加上你的dll的lib文件,你可以把lib文件拷贝到你当前的源程序目录底下就行了。

    1 头文件的设置:将动态链接库工程中的头文件复制到MFC工程下,一般可以在MFC工程下新创建一个Include文件夹用于存放头文件,然后点击Tools-Options-Directorys将Include目录的路径添加到列表中

    2 lib文件设置:在MFC工程中添加一个Lib文件夹,将动态链接库工程生成的Lib文件添加到该文件夹中,然后点击Project-Setting-Link在Object/Library Modules中添加lib文件的相对路径+文件名

    3 dll文件的设置:直接将动态链接库生成的Dll文件添加到MFC工程的Debug或Release目录中(取决于你添加的dll是以Debug方式还是Release方式编译的),也可以新建一个目录专门用于存放Dll,不过需要在系统中进行对应的环境变量设置

    隐式链接就是在程序开始执行时就将DLL文件加载到应用程序当中。实现隐式链接很容易,只要将导入函数关键字_declspec(dllimport)函数名等写到应用程序相应的头文件中就可以了。下面的例子通过隐式链接调用MyDll.dll库中的Min函数。首先生成一个项目为TestDll,在DllTest.h、DllTest.cpp文件中分别输入如下代码:

    //Dlltest.h
    #pragma comment(lib,"MyDll.lib")
    extern "C"_declspec(dllimport) int Max(int a,int b);
    extern "C"_declspec(dllimport) int Min(int a,int b);
    //TestDll.cpp
    #include<stdio.h>
    #include"Dlltest.h"
    void main()
    {
     int a;
     a=min(8,10)
     printf("比较的结果为%dn",a);
    }

      在创建DllTest.exe文件之前,要先将MyDll.dll和MyDll.lib拷贝到当前工程所在的目录下面,也可以拷贝到windows的System目录下。如果DLL使用的是def文件,要删除TestDll.h文件中关键字extern "C"。TestDll.h文件中的关键字Progam commit是要Visual C+的编译器在link时,链接到MyDll.lib文件,当然,开发人员也可以不使用#pragma comment(lib,"MyDll.lib")语句,而直接在工程的Setting->Link页的Object/Moduls栏填入MyDll.lib既可。

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

    10.29

    HINSTANCE hDll;//DLL句柄 如果为类变量,则LoadLibrary为0xcccccccc

    有关DLL的DEF,把导出函数写在里面则工程程序调用其句柄不为空

    unresolved external symbol "class CString __cdecl LinkAndDealDll(char *)" (?LinkAndDealDll@@YA?AVCString@@PAD@Z)

    如果带参数就无此错误

    应该是无正确连接LIB导致

    是呀,字符串不能直接用=
    可以用strcpy(buffer, "sdafdsaf")这样的

    出现0000005的问题

    有可能是CString空间分配问题.

     strcpy(buffer, "s");

     

     lib文件可以放在当前工作目录下,然后头文件定义可以引入.h.

    不用写函数

      int   nCount   =   0;  
     if(!rs.IsBOF())             
     {
      rs.MoveFirst();
      while(!rs.IsEOF()) 
      {
       nCount++;
       rs.MoveNext();  
      }
     }//if

    把char数组清空

    memset(fingerbuffer2, 0,   300);

    第一个是 地址头指针
    第二是 以什么填充
    第三是 长度

    c++里面0=NULL所以该方法可行.

    memset(&fingerbuffer1[0], 0,   300);

    memset(&fingerbuffer1[0], '  ',   300);//注意' '之间有空格,不过不合适不是""

     db->ExecuteSQL("select * from table1");    //检查所有记录
     rs.MoveFirst();          //必须,否则变为无效果游标

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

    11.1

     HICON   hIconNormal   =   AfxGetApp()->LoadIcon(IDR_MAINFRAME);
     this->SetIcon(hIconNormal,true);

    可以设置当前ICON

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

    11.3

     k[0]='0'+((c>>4)&0x0f);

    +比&运算早

    为什么出现<>=呢

    因为字符刚好为10以上然后+0x30就出现该符号

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

    11.5

    检查录入语句可以在sql语句前加断点

    sql最长不为256,可以更长

    TrimLeft方法的意义是:从字符串左边看起,遇到括号中出现的字符(参数)全部截去,直到出现第一个括号中未出现的字符时停止截除,即使后面又出现了参数中有的字符也不会截去了。

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

    11.7

    lstrcpy直接将CString 转为char数组

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

    2008.4.28

    m_listCtrl.SetItemState(0,~LVIS_SELECTED,LVIS_SELECTED);

    取消clistctrl选中

    阅读(2945) | 评论(4)


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

    评论

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