◆ SetWindowsHookEx:安装钩子过程,安装到HOOK链,来监视系统的某些事件,他可以和某个线程相关,或者来监视某些类型的事件
◆ HHOOK SetWindowsHookEx(
int idHook, //指定钩子过程的类型
HOOKPROC lpfn, //HOOK过程
HINSTANCE hMod,
DWORD dwThreadId //为零表示和所有安装的线程相关
);
HOOKPROC lpfn, //HOOK过程
HINSTANCE hMod,
DWORD dwThreadId //为零表示和所有安装的线程相关
);
◆ GetCurrentThreadId获得当前线程的句柄
◆ 屏蔽鼠标过程,首先在BOOL CInnerHookerDlg::OnInitDialog()中添加
SetWindowsHookEx(WH_MOUSE,MouseProc,NULL,GetCurrentThreadId());
SetWindowsHookEx(WH_MOUSE,MouseProc,NULL,GetCurrentThreadId());
◆ 鼠标过程MouseProc为:
LRESULT CALLBACK MouseProc(
int nCode,
WPARAM wParam, //鼠标信息的标识
LPARAM lParam //指向MOUSEHOOKSTR UCT的一个指针
)
LRESULT CALLBACK MouseProc(
int nCode,
WPARAM wParam, //鼠标信息的标识
LPARAM lParam //指向MOUSEHOOKSTR UCT的一个指针
)
◆ CallNextHookEx返回在钩子链的下一个的钩子的钩子过程,在钩子链中有多个钩子过程
◆ 屏蔽键盘消息:HHOOK g_hKeyBoard;
g_hKeyBoard=SetWindowsHookEx(WH_KEYBOARD,KeyBoardProc,NULL,GetCurrentThreadId());
LRESULT CALLBACK KeyBoardProc(
int nCode,
WPARAM wParam,
LPARAM lParam
)
{
if(VK_SPACE==wParam) //VK_SPACE为设备虚拟码,表示空格
//如果你连Alt+F4都想屏蔽,添加以下判断语句
//if(VK_F4==wParam && (lParam>>29 & 1))
//lParam右移29位,正好它的第二十九位在第一位上,lParam得第二十九位表示了Alt键//被按下
return 1;
else
return CallNextHookEx(g_hKeyBoard,nCode,wParam,lParam);
//返回下一个hook
}
int nCode,
WPARAM wParam,
LPARAM lParam
)
{
if(VK_SPACE==wParam) //VK_SPACE为设备虚拟码,表示空格
//如果你连Alt+F4都想屏蔽,添加以下判断语句
//if(VK_F4==wParam && (lParam>>29 & 1))
//lParam右移29位,正好它的第二十九位在第一位上,lParam得第二十九位表示了Alt键//被按下
return 1;
else
return CallNextHookEx(g_hKeyBoard,nCode,wParam,lParam);
//返回下一个hook
}
◆ 关闭HOOK:UnhookWindowsHookEx
g_hWnd=m_hWnd;
接下来为键盘钩子过程添加代码:
if(VK_F2==wParam)
{
::SendMessage(g_hWnd,WM_CLOSE,0,0); //发送关闭消息
UnhookWindowsHookEx(g_hKeyBoard);
UnhookWindowsHookEx(g_hMouse);
接下来为键盘钩子过程添加代码:
if(VK_F2==wParam)
{
::SendMessage(g_hWnd,WM_CLOSE,0,0); //发送关闭消息
UnhookWindowsHookEx(g_hKeyBoard);
UnhookWindowsHookEx(g_hMouse);
}
return 1;
return 1;
}
◆得到动态链接库模块的句柄。
1。DllMain函数方式:
HINSTANCE g_hInst;
1。DllMain函数方式:
HINSTANCE g_hInst;
BOOL WINAPI DllMain(
HINSTANCE hinstDLL,
DWORD fdwReason,
LPVOID lpvReserved
)
{
g_hInst=hinstDLL;
}
HINSTANCE hinstDLL,
DWORD fdwReason,
LPVOID lpvReserved
)
{
g_hInst=hinstDLL;
}
HMODULE和HINSTANCE可以通用
◆2。GetModuleHandle函数方式
SetWindowsHookEx(WH_MOUSE,MouseProc,GetModuleHandle("Hook"),0);
这样我们所安装的钩子过程就和运行在同一个桌面上的所有进程相关了
SetWindowsHookEx(WH_MOUSE,MouseProc,GetModuleHandle("Hook"),0);
这样我们所安装的钩子过程就和运行在同一个桌面上的所有进程相关了
之后新建一个模块文件Hook.def,添加代码:
LIBRARY Hook
LIBRARY Hook
EXPORTS
SetHook @2 //@2用来指定序号。
SetHook @2 //@2用来指定序号。
接下来新建一个工程,用来测试刚才的DLL
在BOOL CHookTestDlg::OnInitDialog()前声明SetHook函数
_declspec(dllimport) void SetHook();
在BOOL CHookTestDlg::OnInitDialog()前声明SetHook函数
_declspec(dllimport) void SetHook();
直接在OnInitDialog()中调用,
SetHook(m_hWnd)。
调试运行,你会发现你的鼠标坏了。
SetHook(m_hWnd)。
调试运行,你会发现你的鼠标坏了。
◆ 如果想让程序窗口始终在其他窗口之前,可以使用SetWindowPos函数
◆ BOOL SetWindowPos( HWND hWnd,
HWND hWndInsertAfter,
int X,
int Y,
int cx,
int cy,
UINT uFlags
);
HWND hWndInsertAfter,
int X,
int Y,
int cx,
int cy,
UINT uFlags
);
◆ 如果要得到窗口的大小,可以使用函数GetSystemMetrics
◆ int GetSystemMetrics(int nIndex);
代码:
int cxScreen,cyScreen;
cxScreen=GetSystemMetrics(SM_CXSCREEN);
cyScreen=GetSystemMetrics(SM_CYSCREEN);
SetWindowPos(&wndTopMost,0,0,cxScreen,cyScreen,SWP_SHOWWINDOW);
SetHook(m_hWnd);
这样的话,我们的程序始终处于顶层窗口,不管怎样切换窗口,整个窗口都只有我们一个程序
代码:
int cxScreen,cyScreen;
cxScreen=GetSystemMetrics(SM_CXSCREEN);
cyScreen=GetSystemMetrics(SM_CYSCREEN);
SetWindowPos(&wndTopMost,0,0,cxScreen,cyScreen,SWP_SHOWWINDOW);
SetHook(m_hWnd);
这样的话,我们的程序始终处于顶层窗口,不管怎样切换窗口,整个窗口都只有我们一个程序
◆ 显示动态链接库的节,可以使用命令行
dumpbin -headers Hook.dll
dumpbin -headers Hook.dll
◆ 因为系统的页面拷贝机制,如果系统发现被共享的DLL被某线程修改,它就会先拷贝一份页面数据,再对原先的页面数据进行修改,共享该DLL的其它线程使用新的页面数据。
◆ 如果确实想在其他程序窗口下关闭我们的程序窗口,可以把共享窗口句柄,使系统不再进行页面拷贝,方法是使用下面语句把窗口句柄设为共享:
#pragma data_seg("MySec")
HWND g_hWnd=NULL; //这里的初始化是必须的,否则没有新建节的信息
#pragma data_seg() //以上为新建节
#pragma data_seg("MySec")
HWND g_hWnd=NULL; //这里的初始化是必须的,否则没有新建节的信息
#pragma data_seg() //以上为新建节
#pragma comment(linker,"/section:MySec,RWS") //设置节的属性,读,写,共享
也可以把#pragma comment(linker,"/section:MySec,RWS")省略。
在Hook.def中添加如下代码:
SEGMENTS
MySec read write shared
也能对节的属性进行设置
也可以把#pragma comment(linker,"/section:MySec,RWS")省略。
在Hook.def中添加如下代码:
SEGMENTS
MySec read write shared
也能对节的属性进行设置
数据库技术
◆ ODBC(Open Database Connectivity),开放数据库互连。ODBC是上个世纪八十年代末九十年代初出现的技术,它为编写关系数据库的客户软件提供了一种统一的接口。ODBC提供一个单一的API,可用于处理不同数据库的客户应用程序。使用ODBC API的应用程序可以与任何具有ODBC驱动程序的关系数据库进行通信。
◆DAO(Data Access Object),数据访问对象。DAO就是一组Microsoft Access/Jet数据库引擎的COM自动化接口。 DAO不像ODBC那样是面向C/C++程序员的,它是微软提供给Visual Basic开发人员的一种简单的数据访问方法,用于操纵Access数据库。
◆ RDO(Remote Data Object),远程数据对象。由于RDO直接调用ODBC API(而不是像DAO那样通过Jet引擎),所以,可以为使用关系数据库的应用程序提供更好的性能
数据库访问技术
◆ OLE DB,对象链接与嵌入数据库。 OLE DB在两个方面对ODBC进行了扩展。首先, OLE DB提供了一个数据库编程的COM接口;第二, OLE DB提供了一个可用于关系型和非关系型数据源的接口。 OLE DB的两个基本结构是OLE DB提供程序(Provider)和OLE DB用户程序(Consumer)。
◆ ADO(ActiveX Data Object),ActiveX数据对象,它建立在OLE DB之上。ADO是一个OLE DB用户程序。使用ADO的应用程序都要间接地使用OLE DB。ADO简化了OLE DB,提供了对自动化的支持,使得像VBScript这样的脚本语言也能够使用ADO访问数据库
□ADO的三个核心对象
Connection对象
Connection对象表示了到数据库的连接,它管理应用程序和数据库之间的通信。Recordest和Command对象都有一个ActiveConnection属性,该属性用来饮用Connection对象。
Command对象
Command对象被用来处理重复执行的查询,或处理需要检查在存储过程调用中的输出或返回参数的值的查询。
Recordset对象
Recordset对象被用来获取数据。Recordset对象存放查询的结果,这些结果又数据的行(称为记录)和列(成为字段)组成。每一列都存放在Recordset的Fields集合中的一个Filed对象中
Connection对象表示了到数据库的连接,它管理应用程序和数据库之间的通信。Recordest和Command对象都有一个ActiveConnection属性,该属性用来饮用Connection对象。
Command对象
Command对象被用来处理重复执行的查询,或处理需要检查在存储过程调用中的输出或返回参数的值的查询。
Recordset对象
Recordset对象被用来获取数据。Recordset对象存放查询的结果,这些结果又数据的行(称为记录)和列(成为字段)组成。每一列都存放在Recordset的Fields集合中的一个Filed对象中
□ VB中用ADO技术访问数据库
工程,组件
在VB中添加ACTIVEX控件:Microsoft ADO Data Control6.0
将其放到窗体上
在控件的属性页:“GENEARL”,选择连接字符串,选择微软的SQL。
选择SQL的连接,输入服务器的名称
在控件的属性页:“RECORDSOURCE”命令的类型我们可以选择:2-adCmdTable
添加数据网格控件:Microsoft DataGrid Control6.0,选择DataSource属性来选择数据库,
□ 添加ADO对象:工程,引用,Microsoft ActiveX Data Object2.6
Private Sub Command1_Click()
Dim conn As New ADODB.Connection
Dim rst As New ADODB.Recordset
Dim cmd As New ADODB.Command
‘这个是连接数据库的连接字串
conn.Open
conn.ConnectionString = "Provider=SQLOLEDB.1;Persist Security Info=False;User ID=sa;Initial Catalog=pubs"
Set rst = conn.Execute("select * from authors")
Do Until rst.EOF
List1.AddItem rst("au_lname")
rst.MoveNext
Loop
End IF
◆ Connection。Recordset。Command都可以使用SQL语句来查询表
VC里面访问数据库
新建一个工程,在StdAfx.h文件中添加以上的代码:
#import "D:/Program Files/Common Files/System/ado/msado15.dll" no_namespace rename("EOF","rsEOF")
然后添加代码:
void CAdoDlg::OnBtnQuery()
{
// TODO: Add your control notification handler code here
CoInitialize(NULL);
_ConnectionPtr pConn(__uuidof(Connection));//这是一个智能指针
_RecordsetPtr pRst(__uuidof(Recordset));
_CommandPtr pCmd(__uuidof(Command));
pConn->ConnectionString="Provider=SQLOLEDB.1;Persist Security Info=False;User ID=sa;Initial Catalog=pubs";
pConn->Open("","","",adConnectUnspecified);
//pRst=pConn->Execute("select * from authors",NULL,adCmdText);
//pRst->Open("select * from authors",_variant_t((IDispatch*)pConn),
// adOpenDynamic,adLockOptimistic,adCmdText);
pCmd->put_ActiveConnection(_variant_t((IDispatch*)pConn));
pCmd->CommandText="select * from authors";
pRst=pCmd->Execute(NULL,NULL,adCmdText);
while(!pRst->rsEOF)
{
((CListBox*)GetDlgItem(IDC_LIST1))->AddString(
(_bstr_t)pRst->GetCollect("au_lname"));
pRst->MoveNext();
}
pRst->Close();
pConn->Close();
pCmd.Release();
pRst.Release();
pConn.Release();
CoUninitialize();
}
◆COM:The Component Object Model组件对象模型