1. 程式人生 > >孫鑫VC學習(第20課-HOOK過程和資料庫)

孫鑫VC學習(第20課-HOOK過程和資料庫)

鉤子過程主要是通過函式SetWindowsHookEx來實現的,現在是對WH_MOUSE進行螢幕,首先,新建一個基於對話方塊的MFC的EXE程式,在BOOL CSXLSN20Dlg::OnInitDialog()中加入如下程式碼:
HHOOK hmyHook;
hmyHook = SetWindowsHookEx(WH_MOUSE,(HOOKPROC)(MouseProc),NULL,GetCurrentThreadId());
hmyHook = SetWindowsHookEx(WH_KEYBOARD,(HOOKPROC)(KeyboardProc),NULL,GetCurrentThreadId());

在CSXLSN20Dlg::OnInitDialog()函式之前加入如下的鉤子函式:

LRESULT __stdcall MouseProc(
  int nCode,      // hook code
  WPARAM wParam,  // message identifier
  LPARAM lParam   // mouse coordinates
  ) 
{
return -2;//return >=1||<0;MOUSE訊息被遮蔽了。return 0;MOUSE訊息沒有被遮蔽了。
}
LRESULT CALLBACK KeyboardProc(
 int code,       // hook code
 WPARAM wParam,  // virtual-key code
 LPARAM lParam   // keystroke-message information
 )
{
//if(wParam == 13) return 0;//13==VK_RETURN
//if(wParam == VK_RETURN || (1==(lParam>>29 & 1 ) && wParam == VK_F4)) return 1;//只遮蔽return 1;訊息,其餘訊息不管,照系統預設的來處理 
//else return CallNextHookEx(g_keyboardHook,code,wParam,lParam);
//return 2;//return >=1||<0;WH_KEYBOARD訊息被遮蔽了。return 0;KEYBOARD訊息沒有被遮蔽了。
if(wParam == VK_F2)//輸入F2,程式直接退出
{
SendMessage(m_mywnd1,WM_CLOSE,0,0);
UnhookWindowsHookEx(g_keyboardHook);//把鍵盤的鉤子過程取消,同理,可以取消滑鼠的鉤子過程
}
return 1;
}

將當前正在執行的所有執行緒的滑鼠和鍵盤訊息。安裝鉤子的程式碼要放到DLL中實現,下面就編寫一個DLL。
新建一個WIN32的DLL工程,名字為HookDll。
原始檔HookDll.cpp中的程式碼為:

#include <windows.h>
HHOOK g_hMouse;
HHOOK g_keyBoard;
HWND g_hwnd;
/*HINSTANCE g_hinst;
BOOL WINAPI DllMain(
HINSTANCE hinstDLL,  // handle to the DLL module
DWORD fdwReason,     // reason for calling function
LPVOID lpvReserved   // reserved
)
{
g_hinst = hinstDLL;
return TRUE;
}
*/
LRESULT CALLBACK MouseProc(
  int nCode,      // hook code
  WPARAM wParam,  // message identifier
  LPARAM lParam   // mouse coordinates
  )
{
return 1;
}
LRESULT CALLBACK KeyboardProc(
 int code,       // hook code
 WPARAM wParam,  // virtual-key code
 LPARAM lParam   // keystroke-message information
 )
{
if (VK_F12 == wParam)
{
SendMessage(g_hwnd,WM_CLOSE,0,0);
UnhookWindowsHookEx(g_hMouse);
UnhookWindowsHookEx(g_keyBoard);
return 0;
}
return 1;
}
void setHook(HWND hwnd)
{
//HHOOK g_hMouse = SetWindowsHookEx(WH_MOUSE,MouseProc,g_hinst,0);
g_hwnd = hwnd;
g_hMouse = SetWindowsHookEx(WH_MOUSE,MouseProc,GetModuleHandle("HookDll"),0);
g_keyBoard = SetWindowsHookEx(WH_KEYBOARD,KeyboardProc,GetModuleHandle("HookDll"),0);
}

HookDll.def中的程式碼為:
LIBRARY HookDll
EXPORTS
setHook   @2;@2表示不想用系統匯出的序號,想自己人為的改變這個函式的序號為2

工程/設定/link/object library modules中填入要連結的LIB檔案的路徑和名字,也可以,這種方法和把LIB檔案放到測試目錄下面是一樣的效果。
在BOOL CHookDllTestDlg::OnInitDialog()加入如下程式碼:
//_declspec (dllimport) void setHook(HWND hwnd);//這個是靜態載入的方法,記得在SETTING中設定一下……
BOOL CHookDllTestDlg::OnInitDialog()
{
//下面是動態載入的方法
// TODO: Add extra initialization here
HINSTANCE hinstLib = LoadLibrary("HookDll.dll"); 
typedef VOID (*MYPROC)(HWND hwnd); 
if (hinstLib != NULL) 

MYPROC ProcAdd= (MYPROC) GetProcAddress(hinstLib, "setHook"); 
ProcAdd(m_hWnd);

FreeLibrary(hinstLib);
//setHook(m_hWnd);//這個是靜態載入的方法,記得在SETTING中設定一下,還要把DLL放在呼叫的資料夾下面
return TRUE;  // return TRUE  unless you set the focus to a control
}
此時可以看到,桌面上的所有執行緒的滑鼠訊息已經被遮蔽了。

接下來讓使用者始終看到我這個視窗,可以把這個視窗設定為頂層視窗,大小等於螢幕的大小,這樣使用者就看不到其它的視窗了。可以在CHookDllTestDlg::OnInitDialog()加入如下程式碼:SetWindowPos( &wndTopMost , 0, 0, GetSystemMetrics(SM_CXSCREEN), 
GetSystemMetrics(SM_CYSCREEN), SWP_NOMOVE|SWP_SHOWWINDOW  );但是此時的F12退出鍵只是針對本程序的,這是因為雖然DLL中的函式是對全體程序而言的,但是各個程序中的資料都有自己的COPY,資料不同步,如果想讓F2變成所有程序的退出鍵,可以採用如下的辦法:
此時只有按ALT+TAB把程式調到這個測試DLL的EXE時(被啟用時),按F12才會起作用,如果在其它程式上面,F12沒有起作用。原因分析:理論上所有程序可以共享DLL中的資料,但是WINDOWS採用了寫入時COPY的機制,每個程序都有自己的資料,為了讓F12對所有程序有效,設計一個結,然後讓所有的程序共享這一個節,先看一下這個DLL的各個節的列表(進入DLL的DEBUG目錄下,dumpbin -headers HookDll.dll)可以看到有很多節,像.text這個節,編譯器在編譯的時候就會把程式碼都放到這個.text這個節中,對於每個標準的節,都是以.開始的,每個節的資訊許可權等資訊在下面都有。我們可以建立一個新的節,把變數放到這個新建立的節中。
如下是建立一個新的節,下面程式碼在DLL中新增如下程式碼:
#pragma data_seg( "MY_DATA" )  //注意名字不能超過8個,不然會自動截斷
HWND g_hwnd=NULL;       //將g_hwnd這到這個節中,其餘變數放到原先的節中,節中變數必須被初始化
#pragma data_seg( )
然後把節設定為共享的節,這樣可以讓多個程序共享,程式碼如下,在DLL中寫下如下程式碼
#pragma comment(linker, "/SECTION:MY_DATA,RWS")//RWS表示這個節是讀寫共享
除了上述方法,還可以用下述方法把節變成一個共享的節:
在DEF檔案中寫如下程式碼:
SEGMENTS
MY_DATA READ WRITE SHARED   //讀寫和共享可以是小寫字母,大小寫無所謂
這裡重新編譯DLL工程,再重新執行DLLTEST工程,就可以在其它程序啟用的時候,按F12退出了,因為這裡的g_hwnd成了一個共享的資料,所以就都有效了。因為控制代碼值是同一個,當在傳送WM_CLOSE傳送訊息時,就給這個控制代碼的視窗傳送WM_CLOSE訊息,那麼呼叫者的視窗就退出了。

下面看看資料庫程式設計方面:
先在VB中看下如何利用ADO訪問資料庫。VB中有一個ADO控制元件,在VB中增加ADO控制元件的方法,在空白的地方選擇 部件,選擇microsoft ADO Data Control 6.0(SP6),將它放到窗體上,在控制元件上面右擊屬性,彈出GENERAL頁面,選擇using connection string,單擊build,在這個上面選擇OLE DB的provider,點選for SQL Server的那個選項,點選下一步,在選擇或輸入伺服器名稱中,如果在本地機器上,可以輸入.或者不輸入,如果在遠端機器上,要輸入伺服器的名字,然後輸入名稱和密碼,如果選擇不上,在選擇資料庫的時候會失敗,選擇pubs資料庫,這個裡面主要存放發行的圖書和版本資訊,點選測試連線,確定確定,再到recordsource下面,COMMAND TYPE選擇 2.adcmdTable,表選擇author,點選確定。接下來再新增一個控制元件,此控制元件叫資料網格控制元件,microsoft dataGrid control 6.0(SP6),在窗體上面放一個數據網格控制元件,在它的datasoruce屬性下面選擇adodc1,執行,就可以看到其中的一些資料,在此控制元件中改變的資料會儲存到資料庫當中,這個資料庫應用可以對一個數據庫進行查詢並修改它。在資料網格上面右鍵,選擇屬性中的通用,選中允許新增和允許刪除,就可以新增和刪除資料了。

接下來用ADO的物件訪問資料庫,再開啟一個VB工程,要在VB環境中新增ADO物件,在工程中新增引用,選擇microsoft active data controls 2.6 library,選擇VIEW 物件瀏覽器,可以檢視ADODB,可以看到有很多物件,在窗體中放置一個列表框和BUTTON,點選BUTTON編輯程式碼,

下面是MFC中的資料庫的應用:
新建一個基於對話方塊的MFC程式,先在MFC程式中匯入"C:\Program Files\Common Files\System\ado\msado15.dll" 這個DLL,它是ADO2.6的版本,在stdafx.h中,加入如下語句:#import "C:\Program Files\Common Files\System\ado\msado15.dll" no_namespace rename("EOF","rsEOF")//no_namespace無名稱空間,說明這是唯一的,因為檔案的結尾也是EOF,為了避免混淆,在匯入ADO庫的時候要重新命名一下,這時在這個MFC程式的檔案目錄下面的DEBUG目錄下,有msado15.tlh(可以看作標頭檔案)和msado15.tli(可以看作原始檔)  這2個檔案,把這2個檔案加入到這個 MFC的工程下,可以看到這2個檔案內容,這2個檔案是當匯入ADO庫的時候,編譯器在編譯的時候自動生成的,當我們利用ADO技術訪問資料庫的時候,不需要匯入這2個檔案,我們匯入只是為了檢視方便。OLEDB是基於COM技術編寫的,ADO是基於OLEDB技術基礎之上的,它是OLEDB的客戶程式,ADO本身也是一個COM元件,要使用COM元件,首先要初始化一個COM庫,




相關推薦

VC學習20-HOOK過程資料庫

鉤子過程主要是通過函式SetWindowsHookEx來實現的,現在是對WH_MOUSE進行螢幕,首先,新建一個基於對話方塊的MFC的EXE程式,在BOOL CSXLSN20Dlg::OnInitDialog()中加入如下程式碼:HHOOK hmyHook;hmyHook

VC學習筆記:八講 逃跑按鈕的巧妙實現MFC中指標的獲取

MFC應用程式中指標的使用    1) 在View中獲得Doc指標 CYouSDIDoc *pDoc=GetDocument();一個視只能有一個文件。    2) 在App中獲得MainFrame指標    CWinApp 中的 m_pMainWnd變數就是MainFrame的指標也可以: CMai

機器學習中的概率模型概率密度估計方法及VAE生成式模型詳解之八4章 之 AEVBVAE

RM mes 9.png size mar evb DC 機器 DG ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

Bobo老師機器學習筆記-PR曲線ROC曲線

在上篇文章中,我們已經概述了PR曲線。現在做個簡單的迴歸 1、什麼是PR曲線?  PR曲線是精準率(Precision)和召回率(Recall)的縮寫, 精準率表示在預測的關注事件中,其中預測正確的有多少。  Precision = TP / (TP + FP)

安卓權威編程指南-筆記24章 Looper Handler HandlerThread

結果 pan color font 特定 消息循環 現在 返回 消息 AsyncTask是執行後臺線程的最簡單方式,但它不適用於那些重復且長時間運行的任務。 1. Looper Android中,線程擁有一個消息隊列(message queue),使用消息隊列的線程叫做

JDBC學習三、DDL、DMLDQL

 一、DDL操作    我們來建立一張學生表,欄位我們給id,name,age,要求id主鍵,自增程式碼演示:package sql; import java.sql.Connection; import java.sql.DriverManager; import jav

VC++ this指標的問題

最近看一個古老但經典的VC++視訊,看到第三課的時候,遇到一個小小的比較特殊的問題,就是子類的物件呼叫父類時,在父類裡的this指標指向的是子類的物件。邏輯上感到有點混亂,用一段程式碼加以驗證。 #include <iostream.h> class P

接口測試學習-python面向對象編程

公有 屬性和方法 定義 無法 eight self 析構 () 每一個 以前都是面向過程編程,做一件事是按順序來的,必須經過很多操作。現在是面向對象編程,將各種操作集合在一起,然後指揮其適用於多個場景。上課時老師舉了一個蠻貼切的例子,比如買車,面向過程就是先去學車,然後去4

接口測試學習-python數據驅動測試

檢查 QQ PE pat spl spa 授權 記錄日誌 日誌格式 自動化分為三類,數據驅動即根據數據去進行測試;代碼驅動即測試都是通過代碼完成的;關鍵字驅動即依靠一些軟件,利用關鍵字完成測試。本次主要記錄數據驅動,自動化框架主要有以下幾個部分: ①獲取用例 ②調用接口

20 - 深入特權級轉移

深入理解呼叫門     呼叫門用於 向高特權級的程式碼段轉移(CPL >= DPLobject)     呼叫門描述符的特權級 低於當前特權級(CPL <= DPLgate)      關於

Python學習20篇】:互斥鎖以及程序之間的三種通訊方式IPC以及生產者個消費者模型 python併發程式設計之多程序1-----------互斥鎖與程序間的通訊

python併發程式設計之多程序1-----------互斥鎖與程序間的通訊 一、互斥鎖 程序之間資料隔離,但是共享一套檔案系統,因而可以通過檔案來實現程序直接的通訊,

Python學習20篇】:互斥鎖以及進程之間的三種通信方式IPC以及生產者個消費者模型

數量 release value body pan sin 回收 dom 之前 python並發編程之多進程1-----------互斥鎖與進程間的通信 一、互斥鎖 進程之間數據隔離,但是共享一套文件系統,因而可以通過文件來實現進程直接的通信,但問題

學習HadoopHadoop初始化測試

        上節我們修改了5個配置檔案,這節我們開始學習Hadoop初始化和測試,首先我們需要Hadoop的環境變數,輸入命令:vim /etc/profile並按回車進入配置檔案,如下圖所示,我

VC++深入詳解——學習筆記

第1課 Windows程式內部執行機制 1.MFC生成的C++原始檔中都有StdAfx.h,此檔案包含了常用的AFX函式的宣告,其中有afxwin.h,此檔案包含了CRECT,CPoi

加州理工學院公開課:機器學習與資料探勘_誤差噪聲

這一課的主題是:誤差分析與噪聲處理。 該課時的主要內容如下: 1、Nonlinear Transformation(Continue)(非線性轉換(續)) 2、Error Measure (誤差度量)(重點) 3、Noisy Targets(噪聲指標)(重點) 4、Prea

C++基礎學習筆記----const引用的擴充套件、過載函式C方式編譯的深入

主要講了const和引用的一些擴充套件和注意事項,過載函式的和extren "C"結合使用的本質,以及引用的真正的理解方式。 const的引用 擴充套件使用方法 1.通過const引用的變數是隻讀變數,當使用const_cast經過強制型別轉換後引用將會降級為普通變數,通過

vc++ 17 程序間通訊3 命名管道

一、基礎知識 1.命名管道 (1)命名管道是圍繞Windows檔案系統設計的一種機制,採用“‘命名管道檔案系統’(Named Pipe File System,NPFS)“介面 (2)命名管道通過網路來完成程序間的通訊,它遮蔽了底層的網路協議細節;命名管道不僅可以在本機上實

C++基礎學習筆記----建構函式

本節主要講物件的初始化、建構函式的基本概念使用方法以及兩個特殊的建構函式,課後練習是手寫陣列類。 物件的初始化 所有的物件都需要一個確定的初始狀態。這樣我們可以使用一個initialize函式來進行初始化。物件在建立後可以呼叫這個函式進行初始化。 initialize在這

軟工實踐學習三次

bsp ima 增刪改查 pri 增刪 ext 處理 logs ring 經過這一段時間的ssh框架學習,通過老師帶我們完成一個項目後,我們需要自己從0開始,開始新的項目,重新搭建框架 這次我選擇的是庫存管理系統 首先依然是搭建hibernate,以及spring。

11 std::bindstd::function2_std::bind綁定器

pan std name iostream emf end cnblogs left eid 1. 溫故知新:std::bind1st和std::bind2nd (1)bind1st、bind2nd首先它們都是函數模板,用於將參數綁定到可調用對象(如函數、仿函數等)的第1個