API技巧集

API技巧集(一)


一、拖動無標題窗體:

包含頭文件:

#include “winuser.h“

在窗體或組件的 OnMouseDown 事件中加入以下代碼:

if(Button == mbLeft)
{
ReleaseCapture();
SendMessage( Handle, WM_NCLBUTTONDOWN, HTCAPTION, 0);
}

二、彈出和關閉光驅:

包含頭文件:

#include “mmsystem.h“
在窗體的OnCreate事件中加入:

mciSendString("open cdaudio alias cd wait shareable",0,0,0);

1、要彈出光驅時使用:

mciSendString("set cd door open",0,0,0);

2、要關閉光驅時使用:

mciSendString("set cd door closed",0,0,0);

三、提取圖標:

包含頭文件:

#include “shellapi.h“

例子:

TIcon *Icon = new TIcon();
AnsiString FileName = "C://WINDOWS//SYSTEM//SHELL32.DLL";
int TotalIcon;

//得到文件SHELL32.DLL的總圖標數
TotalIcon = (int)ExtractIcon(Form1->Handle,FileName.c_str(), -1);

//提取第一個圖標,0爲第一個,1爲第二個,類推...
Icon->Handle = ExtractIcon( Form1->Handle, FileName.c_str(), 0);

//保存圖標
Icon->SaveToFile("C://1.ICO");

四、設置頂端窗口(永在上面):

包含頭文件:

#include “winuser.h“

1、設置頂層窗口

SetWindowPos( Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE||SWP_NOSIZE);

2、取消頂層窗口

SetWindowPos( Handle, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE||SWP_NOSIZE);

API技巧集 (二)

12/3/2000 0:0:0··符東亮··yesky

  (一)不規則窗口

  Windows提供的只是標準的矩形窗口,要想建立一個不規則的窗口就需要調用API函數來實現。建立一個不規則的窗口,一般是先用創建區域的API函數建立一個不規則的區域,再用API函數SetWindowRgn改變窗口的區域。這些API函數在C++ Builder中包含在頭文件wingdi.h和winuser.h裏面,因此,要使用這些API函數就要先在程序頭部加上包含頭文件的語句:

include “wingdi.h“

include “winuser.h“

  SetWindowRgn函數能改變一個窗口的區域,該函數有三個參數,第一個參數hWnd是欲設置區域的窗口句柄,第二個參數hRgn是欲設置的區域,第三個參數bRedraw一般設爲true,即立即重畫窗口。

  用來創建區域的API函數有多個,最常用的有三個:

  1、CreateRectRgn函數,用來創建一個由X1、Y1和X2、Y2座標點確定的矩形區域。當座標點X1和Y1相等、X2和Y2也相等的時候,創建的是一個正方形。

  例子:

//創建長方形

HRGN hRect=CreateRectRgn(0,0,400,200);

SetWindowRgn(Handle,hRect,true);

//創建正方形

HRGN hRect=CreateRectRgn(0,0,300,300);

SetWindowRgn(Handle,hRect,true);

  2、CreateEllipticRgn函數,用來創建一個由X1、Y1和X2、Y2座標點確定的矩形所內切的橢圓。同樣,X1、Y1和X2、Y2座標點所確定的矩形爲正方形時,創建的就是一個圓形。

  例子:

//創建橢圓

HRGN hElliptic=CreateEllipticRgn(0,0,400,250);

SetWindowRgn(Handle,hElliptic,true);

//創建圓形

HRGN hElliptic=CreateEllipticRgn(0,0,400,400);

SetWindowRgn(Handle,hElliptic,true);

  3、CombineRgn函數,能將兩個區域組合爲一個新區域,它有四個參數,第一個參數hrgnDest保存合併後的新區域,第二個參數hrgnSrc1、三個參數hrgnSrc2爲欲合併的兩個區域,第四個參數fnCombineMode是區域組合的方式,它的值是爲下面組合方式之一:

  組合方式 說明

RGN_AND 建立兩個區域的交集

RGN_COPY 建立hrgnSrc1的拷貝

RGN_DIFF 建立兩個區域不相交的部分

RGN 建立兩個區域的並集

RGN_XOR 建立除兩個區域並集之外的部分

  例子:

//創建一個圓形和長方形交集的組合形狀

HRGN hRect=CreateRectRgn(0,0,300,300);

HRGN hElliptic=CreateEllipticRgn(0,0,400,250);

CombineRgn(hRect,hRect,hElliptic,RGN_OR);

SetWindowRgn(Handle,hRect,true);

  當需要將窗口還原爲標準Windows矩形窗口時,只要將SetWindowRgn函數的hRgn參數設爲0就行了,如:

SetWindowRgn(Handle,0,true);


API技巧集 (二)



  (二)得到系統聲卡的個數

  當我們編寫一個多媒體程序(如播放器)的時候,有時需要檢測一下計算機中是否安裝了聲卡,如果沒有裝聲卡程序則會終止運行。

  在這裏,我們就要使用API函數waveOutGetNumDevs,調用這個函數可返回系統中安裝了的聲卡的個數。在C++ Builder 5.0中,它被包含在頭文件“mmsystem.h”裏面。

  例子:

  1、首先在程序頭部加入包含頭文件的代碼:

#include “mmsystem.h“

  2、在窗體的OnCreate事件中加入下面的代碼:

int Num;

//得到聲卡的個數

Num=waveOutGetNumDevs();

if(Num)

ShowMessage("你有安裝了"+IntToStr(Num)+"塊聲卡");

else

{

ShowMessage("你沒有安裝聲卡!/n程序終止運行!");

Close();

}

  3、編譯運行程序。

API技巧集 (二)


  (三)獲得、設置鼠標雙擊的間隔時間

  在指定間隔的時間內,連續兩次鼠標單擊操作稱爲雙擊,雙擊間隔的時間可以在控制面板中的鼠標屬性裏面改變。若要在自編的應用程序中能獲得或設置鼠標雙擊的間隔時間,我們只需使用Windows的兩個API函數GetDoubleClickTime和SetDoubleClickTime。調用GetDoubleClickTime可以返回鼠標雙擊的間隔時間,而使用SetDoubleClickTime則可以設置鼠標雙擊間隔的時間。

  下面讓我們來做一個獲得和設置鼠標雙擊間隔時間的簡單的程序:

  首先,在Borland C++ Builder 5.0 中新建一個工程,往窗體Form1中添加兩個Button組件,把它們的Caption屬性分別改爲“獲取雙擊間隔時間”和“設置雙擊間隔時間”,再添加一個Edit組件,將Edit1的Text屬性改爲“200”,添加一個Label組件,把Caption屬性改爲“毫秒”。

  然後,雙擊按鈕Button1,在它的OnClick(單擊)事件中加入下面的代碼:

//返回鼠標雙擊間隔時間

ShowMessage("鼠標雙擊間隔時間爲"+IntToStr(GetDoubleClickTime())+"毫秒");

  再雙擊按鈕Button2,也在它的OnClick事件中加入代碼:

//設置鼠標雙擊間隔時間

SetDoubleClickTime(StrToInt(Edit1-$#@62;Text));

  最後,按F9編譯運行一下程序。點擊窗口中的“獲取雙擊間隔時間”按鈕就會彈出一個顯示當前系統鼠標雙擊間隔的時間,若要設置鼠標雙擊間隔的時間,只要改變文本框中的數值,比如300吧,再點擊“設置雙擊間隔時間”按鈕就可以了。需要注意的是,鼠標雙擊間隔時間的單位是毫秒,設置的值越小,間隔的時間就越小,雙擊的速度就越快,系統默認的是400毫秒,可不要設得太小了,否則“我的電腦”會打不開的(你雙擊的速度不夠快,^_^)。





 API技巧集 (二)



  (四)啓動控制面板控制檯應用程序

  在控制面板裏有許多的控制面板項目,這些項目就是控制檯應用程序,它們都是標準的DLL(動態鏈接庫)文件,我們經常需要通過它們來對Windows進行配置。rundll32.exe就是專門用來調用DLL文件的程序,在C++ Builder編程中,我們可以通過使用API函數WinExec運行外部程序rundll32.exe調用DLL來實現啓動控制面板的控制檯應用程序。下面是收集的一些調用DLL啓動控制檯應用程序的例子:

  1、打開控制面板  

WinExec("rundll32.exe shell32.dll,Control_RunDLL",SW_SHOWNORMAL);

  2、打開方式對話框

WinExec("rundll32.exe shell32.dll,OpenAs_RunDLL "c://autoexec.bat"",SW_SHOWNORMAL);

  3、添加Modem

WinExec("rundll32.exe shell32.dll,Control_RunDLL modem.cpl,,add",SW_SHOWNORMAL);

  4、添加打印機

WinExec("rundll32.exe shell32.dll,SHHelpShortcuts_RunDLL AddPrinter",SW_SHOWNORMAL);

  5、複製磁盤

WinExec("rundll32.exe diskcopy.dll,DiskCopyRunDll",SW_SHOWNORMAL);

  6、鼠標

WinExec("rundll32.exe shell32.dll,Control_RunDLL main.cpl",SW_SHOWNORMAL);

  7、網絡

WinExec("rundll32.exe shell32.dll,Control_RunDLL netcpl.cpl",SW_SHOWNORMAL);

  8、密碼

WinExec("rundll32.exe shell32.dll,Control_RunDLL password.cpl",SW_SHOWNORMAL);

  9、遊戲控制器

WinExec("rundll32.exe shell32.dll,Control_RunDLL joy.cpl",SW_SHOWNORMAL);

  10、日期/時間

WinExec("rundll32.exe shell32.dll,Control_RunDLL timedate.cpl",SW_SHOWNORMAL);

  11、Internet 屬性
WinExec("rundll32.exe shell32.dll,Control_RunDLL inetcpl.cpl",SW_SHOWNORMAL);

  12、添加/刪除程序

//安裝/卸載

WinExec("rundll32.exe shell32.dll,Control_RunDLL appwiz.cpl,,1",SW_SHOWNORMAL);

//Windows 安裝

WinExec("rundll32.exe shell32.dll,Control_RunDLL appwiz.cpl,,2",SW_SHOWNORMAL);

//啓動盤

WinExec("rundll32.exe shell32.dll,Control_RunDLL appwiz.cpl,,3",SW_SHOWNORMAL);

  13、區域設置

//區域設置

WinExec("rundll32.exe shell32.dll,Control_RunDLL intl.cpl,,0",SW_SHOWNORMAL);

//數字

WinExec("rundll32.exe shell32.dll,Control_RunDLL intl.cpl,,1",SW_SHOWNORMAL);

//貨幣

WinExec("rundll32.exe shell32.dll,Control_RunDLL intl.cpl,,2",SW_SHOWNORMAL);

//時間

WinExec("rundll32.exe shell32.dll,Control_RunDLL intl.cpl,,3",SW_SHOWNORMAL);

//日期

WinExec("rundll32.exe shell32.dll,Control_RunDLL intl.cpl,,4",SW_SHOWNORMAL);

  14、輔助選項

//鍵盤

WinExec("rundll32.exe shell32.dll,Control_RunDLL access.cpl,,1",SW_SHOWNORMAL);

//聲音

WinExec("rundll32.exe shell32.dll,Control_RunDLL access.cpl,,2",SW_SHOWNORMAL);

//顯示

WinExec("rundll32.exe shell32.dll,Control_RunDLL access.cpl,,3",SW_SHOWNORMAL);

//鼠標

WinExec("rundll32.exe shell32.dll,Control_RunDLL access.cpl,,4",SW_SHOWNORMAL);

//常規

WinExec("rundll32.exe shell32.dll,Control_RunDLL access.cpl,,5",SW_SHOWNORMAL);

  15、多媒體

//音頻

WinExec("rundll32.exe shell32.dll,Control_RunDLL mmsys.cpl,,0",SW_SHOWNORMAL);

//視頻

WinExec("rundll32.exe shell32.dll,Control_RunDLL mmsys.cpl,,1",SW_SHOWNORMAL);

//MIDI

WinExec("rundll32.exe shell32.dll,Control_RunDLL mmsys.cpl,,2",SW_SHOWNORMAL);

//CD 音樂

WinExec("rundll32.exe shell32.dll,Control_RunDLL mmsys.cpl,,3",SW_SHOWNORMAL);

//設備

WinExec("rundll32.exe shell32.dll,Control_RunDLL mmsys.cpl,,4",SW_SHOWNORMAL);

  16、系統

//常規

WinExec("rundll32.exe shell32.dll,Control_RunDLL sysdm.cpl,,0",SW_SHOWNORMAL);

//設備管理器

WinExec("rundll32.exe shell32.dll,Control_RunDLL sysdm.cpl,,1",SW_SHOWNORMAL);

//硬件配置文件

WinExec("rundll32.exe shell32.dll,Control_RunDLL sysdm.cpl,,2",SW_SHOWNORMAL);

//性能

WinExec("rundll32.exe shell32.dll,Control_RunDLL sysdm.cpl,,3",SW_SHOWNORMAL);

  17、顯示器

//背景

WinExec("rundll32.exe shell32.dll,Control_RunDLL desk.cpl,,0",SW_SHOWNORMAL);

//屏幕保護

WinExec("rundll32.exe shell32.dll,Control_RunDLL desk.cpl,,1",SW_SHOWNORMAL);

//外觀

WinExec("rundll32.exe shell32.dll,Control_RunDLL desk.cpl,,2",SW_SHOWNORMAL);

//設置

WinExec("rundll32.exe shell32.dll,Control_RunDLL desk.cpl,,3",SW_SHOWNORMAL);  

  這些例子在Windows 98和Windows 2000中都可以使用通過,前提是在控制面板中安裝了該項目。

API技巧集(三) 

  (一)閃爍程序的標題欄

  在某些專業的應用程序中,當程序需要提醒用戶或要引起用戶的注意時,就不停地閃爍程序的標題欄。要實現這個功能,只需要一個Timer組件和使用一個API函數--FlashWindow。

  使用API函數FlashWindow可以閃爍顯示指定窗口,讓窗口在活動與非活動的狀態之間切換,它有兩個參數:hwnd和bInvert,頭文件爲“winuser.h”。其中,參數hwnd爲要閃爍的窗口句柄,參數bInvert是一個bool變量,設爲true時,程序窗口標題欄從活動切換到非活動狀態、或反向切換,當設爲false時,窗口標題欄還原爲最初的狀態。如果配合一個時間組件(Timer組件),以一定的時間間隔執行語句:

FlashWindow(Form1-$#@62;Handle,true);

程序窗口的標題欄就在活動、非活動的狀態之間不停地切換。若把hwnd指定成爲應用程序的句柄(Application-$#@62;Handel),將會閃爍程序在任務欄上的標題欄。

  下面就讓我們來做一個閃爍窗口標題欄和任務欄上標題欄的程序。

  首先,在Form1中添加三個按鈕Button1、Button2和Button3,把它們的屬性分別爲“閃爍窗口標題欄”、“閃爍任務標題欄”和“停止閃爍”,再加入兩個時間組件Timer1和Timer2,將兩個Timer組件的Enabled屬性都設爲false,將Interval屬性都設爲爲500(即半秒),改變這個屬性的值可以修改閃爍的頻率。

  然後,雙擊Timer1,在OnTimer事件中加入:

FlashWindow(Form1-$#@62;Handle,true);

  雙擊Timer2,在OnTimer事件中加入:

FlashWindow(Application-$#@62;Handel,true);

  雙擊Button1,在Button1的OnClick事件中加入:

Timer1-$#@62;Enabled=true;

  雙擊Button2,在Button2的OnClick事件中加入:

Timer2-$#@62;Enabled=true;

  最後,雙擊Button3,在Button3的OnClick事件中加入:

Timer1-$#@62;Enabled=false;

Timer2-$#@62;Enabled=false;

FlashWindow(Form1-$#@62;Handle,false);

FlashWindow(Application-$#@62;Handel,false);

  這樣,一個簡單的例子就完成了。按F9編譯運行程序,你就可閃爍窗口標題欄或是閃爍任務欄上? 題欄了。


  (二)拖動無標題窗體

  現在的Windows應用程序,大都使用了圖形化的界面、不規則窗口技術,使得程序界面更加漂亮了。但是,使用界面一般要先把窗體的標題欄去掉(在BCB中,將窗體的BorderStyle屬性設爲bsNone,就可以把窗體的標題欄去掉),這樣就不能使用原來的標題欄了,出現了窗口不能移動的問題。沒有標題欄怎樣用鼠標拖動窗體呢?我們可以使用Windows的API函數SendMessage來解決這個問題。

  首先,新建一個工程,把窗體的BorderStyle屬性設爲bsNone去掉窗體的標題欄,按F12鍵切換到代碼編輯窗口,在頭部加入包含頭文件"winuser.h"的代碼:

#include $#@60;winuser.h$#@62;

  然後,在窗體的 OnMouseDown 事件中加入下面的代碼:

if(Button == mbLeft)//判斷是否按了鼠標左鍵

{

ReleaseCapture();//釋放鼠標操作

SendMessage( Handle, WM_NCLBUTTONDOWN, HTCAPTION, 0);

}

  這樣,用鼠標左鍵點住窗口拖動,就可以實現拖動沒有標題的窗口了。也可以在窗體上添加組件,然後在該組件的 OnMouseDown 事件中加入上面的代碼,這樣也可以點住這個組件拖動窗口。你還可以把SendMessage函數的第一個參數修改爲這個組件的句柄,如:往窗體添加一個Button組件,在它的 OnMouseDown 事件中加入上面的代碼,其中把SendMessage那行語句改爲:

SendMessage( Button1-$#@62;Handle, WM_NCLBUTTONDOWN, HTCAPTION, 0);

這樣就可以在程序運行時,用鼠標在窗口的範圍內移動Button1了。

  (三)隱藏程序在任務欄的圖標

  使用API函數ShowWindow可以隱藏一個程序在任務欄的圖標,它被包含在頭文件“winuser.h”裏面。

  1、隱藏任務欄圖標的代碼就是:

ShowWindow(Application-$#@62;Handle, SW_HIDE);

  2、要重新顯示的時候就使用:

ShowWindow(Application-$#@62;Handle, SW_SHOW);

  但是,如果將程序最小化後,在任務欄的圖標就會重新出現。若要在程序還原最小化後,程序在任務欄的圖標重新被隱藏起來,可以在窗體的OnPaint事件中加入隱藏程序在任務欄的圖標的代碼,這樣,程序只有在最小化時任務欄纔會出現圖標,當程序還原最小化時圖標又會重新被隱藏起來。


API技巧集(三)




  (四)重啓、關閉Windows

  當用戶修改了Windows裏面的一些設置,Windows經常會提問是否要重新啓動計算機,當用戶點Yes的時候,計算機將會自動重啓。這個就是API函數ExitWindowsEx的一個典型的應用。

  ExitWindowsEx,顧名思義就是退出Windows的函數,它有兩個參數,第一個是退出Windows的選項,常用的有:EWX_REBOOT(重新啓動計算機),EWX_SHUTDOWN(關閉計算機),EWX_LOGOFF(註銷當前用戶),第二個參數系統保留沒有使用,可設爲0。

  在自編的程序中(如:註冊表修改程序),當用戶修改了某項設置需要重新啓動計算機的時候,就要使用EWX_REBOOT選項重啓計算機。如:

ExitWindowsEx(EWX_REBOOT,0);

  使用WX_SHUTDOWN選項,可以實現關機。如:

ExitWindowsEx(EWX_SHUTDOWN,0);

  當需要註銷的時候,就使用EWX_LOGOFF選項。如:

ExitWindowsEx(EWX_LOGOFF,0);

api技巧集(四)



函數名:

  SetWindowPos

頭文件:

  winuser.h

函數原型:

  BOOL SetWindowPos
  (
  HWND hWnd, //窗口句柄
  HWND hWndInsertAfter, //排列順序的句柄
  int X, //水平座標
  int Y, //垂直座標
  int cx, //寬
  int cy, //高
  UINT uFlags //窗口定位標識
  );

說明:

  這個函數能改變窗口的大小、位置和設置子窗口、彈出窗口或頂層窗口的排列順序。
  返回值:

  BOOL,如果返回值非零表示成功,返回零表示失敗。錯誤信息請參看GetLastError函數。

參數表:

  參數 類型及說明
  hwnd HWND,欲定位的窗口句柄
  hWndInsertAfter HWND,置於hwnd前面的窗口句柄。這個參數必須是窗口的句柄或是下面的值之一:   HWND_BOTTOM 將窗口置於其它所有窗口的底部
  HWND_NOTOPMOST 將窗口置於其它所有窗口的頂部,並位於任何最頂部窗口的後面。如果這個窗口非頂部窗口,這個標記對該窗口並不產生影響
  HWND_TOP 將窗口置於它所有窗口的頂部
  HWND_TOPMOST 將窗口置於其它所有窗口的頂部,並位於任何最頂部窗口的前面。即使這個窗口不是活動窗口,也維持最頂部狀態

x: 
 
  int,指定窗口新的X座標

Y:  

  int,指定窗口新的Y座標

cx:  

  int,指定窗口新的寬度

cy:  

  int,指定窗口新的高度

wFlags:

  UINT,指定窗口狀態和位置的標記。這個參數使用下面值的組合: SWP_DRAWFRAME 圍繞窗口畫一個框
  SWP_FRAMECHANGED 發送一條WM_NCCALCSIZE消息進入窗口,即使窗口的大小沒有發生改變。如果不指定這個參數,消息WM_NCCALCSIZE只有在窗口大小發生改變時才發送
  SWP_HIDEWINDOW 隱藏窗口
  SWP_NOACTIVATE 不激活窗口
  SWP_NOCOPYBITS 屏蔽客戶區域
  SWP_NOMOVE 保持當前位置(X和Y參數將被忽略)
  SWP_NOOWNERZORDER 不改變所有窗口的位置和排列順序
  SWP_NOREDRAW 窗口不自動重畫
  SWP_NOREPOSITION 與SWP_NOOWNERZORDER標記相同 r>   SWP_NOSENDCHANGING 防止這個窗口接受WM_WINDOWPOSCHANGING消息
  SWP_NOSIZE 保持當前大小(cx和cy會被忽略)
  SWP_NOZORDER 保持窗口在列表的當前位置(hWndInsertAfter將被忽略)
  SWP_SHOWWINDOW 顯示窗口


備註:

  如果設置了SWP_SHOWWINDOW或SWP_HIDEWINDOW標記,這個窗口不發生移動或改變大小。窗口成爲最頂級窗口後,它的所有子窗口也會進入最頂級。一旦將其設爲非最頂級,則它的所有子窗口也會轉爲非最頂級。

相關函數:

  MoveWindow,SetActiveWindow,SetForegroundWindow

例子:

  //設置頂層窗口
  SetWindowPos( Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE||SWP_NOSIZE);

  //取消頂層窗口
  SetWindowPos( Handle, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE||SWP_NOSIZE);



api技巧集(四)





超級鏈接效果

  在很多共享軟件的關於對話框裏有一些模仿網頁的超級鏈接,如主頁URL或E-Mail之類的,當鼠標移到它上面的時候,文字變成紅色的,當鼠標離開時,文字又變回原來的藍色,如果用鼠標點擊這個鏈接則會彈出瀏覽器窗口打開指定的URL或是運行默認的E-Mail程序撰寫新郵件,就和真的超鏈接一樣。你是不是也想在你的程序裏做一個呢?其實,我們只要調用API函數ShellExecute和在鼠標移動時改變一下文字的顏色,就可以在自己的程序中出現這種效果。

  首先新建一個工程,在窗體Form1上添加兩個Label組件,它們的Name屬性使用默認的Label1和Label2。

  然後在Form1的OnCreate事件中加入代碼:

Label1-$#@62;Cursor=crHandPoint;

Label2-$#@62;Cursor=crHandPoint;

Label1-$#@62;Font-$#@62;Color =clBlue;

Label2-$#@62;Font-$#@62;Color =clBlue;

Label1-$#@62;Caption="主頁:初學者之家網站";

Label2-$#@62;Caption="E-Mail:[email protected]";

  再在Label1的OnClick(單擊)事件中加入:

//藍色的字請改成自己的主頁地址

ShellExecute(Handle,NULL,"http://fdlweb.myrice.com/",NULL,NULL,SW_SHOWNORMAL);

  在OnMouseMove事件中加入:

Label1-$#@62;Font-$#@62;Color=clRed;

  在Label2的OnClick事件中加入:

//藍色的字請改成自己郵箱地址

ShellExecute(Handle,NULL,"mailto:[email protected]",NULL,NULL,SW_SHOWNORMAL);

  在OnMouseMove事件中加入:

Label2-$#@62;Font-$#@62;Color=clRed;

  最後在Form1的OnMouseMove事件中加入:

Label1-$#@62;Font-$#@62;Color=clBlue;

Label2-$#@62;Font-$#@62;Color=clBlue;

  代碼輸入完了,按F9編譯運行程序就看到效果了。



拷貝屏幕

  BitBlt函數可以將一幅位圖從一個設備場景拷貝到另一個設備場景,這個函數經常用在抓圖程序和遊戲編程方面,也可以用來做基於桌面的屏幕保護程序。下面讓我們用BitBlt函數來做一個虛假桌面的程序:

  首先,添加一個Image組件到窗體中,將窗體Form1的BorderStyle屬性設爲:bsNone。

  接着在窗體的OnCreate事件加入程序代碼:

Left=0;

Top=0;

Width=Screen-$#@62;Width;

Height=Screen-$#@62;Height;

Image1-$#@62;Left=0;

Image1-$#@62;Top=0;

Image1-$#@62;Width=Screen-$#@62;Width;

Image1-$#@62;Height=Screen-$#@62;Height;

//這句代碼就是將桌面拷貝到組件Image1中來存放,

// 其中GetDC(0)返回桌面設備的句柄(HDC)

BitBlt(Image1-$#@62;Canvas-$#@62;Handle,0,0,Screen-$#@62;Width,Screen-$#@62;Height,GetDC(0),0,0,SRCCOPY);

  按F9運行,一個假的桌面就出來了,在這個“桌面”上怎麼按鼠標都沒有反應,可以用來捉弄人喔!。有些桌面的小遊戲也是這麼幹的,你可以在這個程序的基礎上加上更多的功能,如在窗體上加上Label組件和Timer組件,用Timer組件來控制Label組件在窗體上移動,再在窗體Form1的OnKeyDown事件和Image1的OnMouseDown事件中加入關閉窗口的代碼“Close();”,最後將編譯了的程序的擴展名改爲scr,這就成了一個文字在桌面上亂動的屏幕保護程序了。






取得磁盤總空間和剩餘空間

  要取得磁盤總空間和剩餘空間,最簡單直接的方法是調用API函數 GetDiskFreeSpace。

  GetDiskFreeSpace函數有5個參數,第一個參數是要判斷可用空間的驅動器名,第二個參數是一個存放每簇扇區數的變量,第三個參數是一個存放每扇區字節數的變量,第四個參數是存放剩餘簇數的變量,第五個參數是存放總簇數的變量。套用相應計算磁盤空間的公式即可得出指定驅動器的總空間或剩餘空間。

磁盤總空間和剩餘空間的計算公式分別爲:

  磁盤上剩餘空間(字節) = 簇的扇區數 * 扇區的字節數 * 剩餘簇數

  磁盤上總空間(字節) = 簇的扇區數 * 扇區的字節數 * 總簇數

下面就是取得C盤的總空間和剩餘空間的例子:

unsigned long Sectors,Bytes,Free,Total;

GetDiskFreeSpace("C://",&Sectors,&Bytes,&Free,&Total);

//可用空間(單位:MB)

int FreeKB = Bytes * Sectors * Free / 1024;

//總空間(單位:MB)

int TotalKB = Bytes * Sectors * Total / 1024;

ShowMessage("C盤的可用空間有:" + IntToStr(FreeKB) + "MB,總空間有:" + IntToStr(TotalKB) +"MB");

api技巧集(五) 

提取圖標


  調用API函數ExtractIcon可以提取出在程序文件中的圖標,它的頭文件是shellapi.h,原型爲:

HICON ExtractIcon
(
HINSTANCE hInst, //實例句柄
LPCTSTR lpszExeFileName, //要提取圖標的那個程序的文件名
UINT nIconIndex //要提取的圖標的索引
);

  調用該函數時,參數hInst一般設爲當前應用程序的實例句柄,如:Form1-$#@62;Handle。

  參數lpszExeFileName爲需要提取圖標的程序文件的完整路徑,這個程序文件可以是EXE文件、DLL文件、ICO文件等,只要是包含有圖標資源的文件一般都可以提取圖標。

  當參數nIconIndex指定一個圖標的索引可以返回指向圖標的句柄,如指定的文件中不存在圖標,則返回零,當參數nIconIndex設爲-1,函數返回文件的圖標總數。

  函數返回的句柄可以賦給一個用TIcon類聲明的變量,再使用該變量的SaveToFile方法就可以把圖標保存出來。

例子:

TIcon *Icon = new TIcon();
AnsiString FileName = "C://WINDOWS//SYSTEM//SHELL32.DLL";
int TotalIcon;
//得到文件SHELL32.DLL的總圖標數
TotalIcon = (int)ExtractIcon(Form1->Handle,FileName.c_str(), -1);
//提取第一個圖標,0爲第一個,1爲第二個,類推...
Icon->Handle = ExtractIcon( Form1->Handle, FileName.c_str(), 0);
//保存圖標
Icon->SaveToFile("C://1.ICO");
  下面給出一個完整的圖標提取程序源碼。

  這個程序需要四個按鈕控件(Button)、四個文本標籤控件(Label)、兩個文本框控件(Edit)、一個水平滾動條控件(ScrollBar)、一個打開文件對話框控件(OpenDialog)、一個保存文件對話框控件(SaveDialog)和一個圖片控件(Image),還有一個Panel控件是裝飾用的。界面如圖所示:

             

  把各個控件排列好,再把四個Label控件的Caption屬性修改一個,最後輸入程序代碼,運行程序,一個提取圖標的程序就出來了,你以後也就不會爲沒有圖標資源可用而發愁了。

程序清單(Unit1.cpp):
//--------------------------------------- ----------------------
#include $#@60;vcl.h$#@62;
#pragma hdrstop
#include "Unit1.h"
//----------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
AnsiString FileName;
TIcon *Icon = new TIcon();
int TotalIcon;
//----------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}

//----------------------------------------------------------------

void __fastcall TForm1::FormCreate(TObject *Sender)
{

Caption="圖標小偷 1.0";
Button1-$#@62;Caption="選擇文件";
Button2-$#@62;Caption="保存圖標";
Button3-$#@62;Caption="保存所有";
Button4-$#@62;Caption="退出";
Edit1-$#@62;Text=0;
Edit2-$#@62;Text=0;
Image1-$#@62;Width=32;
Image1-$#@62;Height=32;
OpenDialog1-$#@62;Filter="可執行文件(*.exe,*.dll)|*.exe;*.dll|圖標文件(*.ico)|*.ico|所有文件(*.*)|*.*";
SaveDialog1-$#@62;Filter="圖標文件|*.ico";
ScrollBar1-$#@62;Enabled=false;
Button2-$#@62;Enabled=false;
Button3-$#@62;Enabled=false;

}
//----------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{

if(OpenDialog1-$#@62;Execute())
{

TotalIcon = (int)ExtractIcon( Form1-$#@62;Handle, OpenDialog1-$#@62;FileName.c_str(), -1 );
if(TotalIcon$#@62;0)
{

if(TotalIcon$#@60;2)

ScrollBar1-$#@62;Enabled=false;

else

ScrollBar1-$#@62;Max=TotalIcon-1;

Button2-$#@62;Enabled=true;
Button3-$#@62;Enabled=true;
FileName = OpenDialog1-$#@62;FileName;
Edit1-$#@62;Text =TotalIcon;
Icon-$#@62;Handle = ExtractIcon( Form1-$#@62;Handle, FileName.c_str(), 0);
Image1-$#@62;Picture-$#@62;Icon=Icon;
Edit2-$#@62;Text=1;

}
else
{

ShowMessage("該文件沒有圖標");

}

}

}
//----------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{

if(SaveDialog1-$#@62;Execute())
{

//保存圖標
Icon-$#@62;SaveToFile( SaveDialog1-$#@62;FileName);

}

}
//----------------------------------------------------------------
void __fastcall TForm1::Button3Click(TObject *Sender)
{

if(SaveDialog1-$#@62;Execute())
//提取所有的圖標
for(int i=0;i$#@60;TotalIcon-1;i++)
{

Icon-$#@62;Handle = ExtractIcon( Form1-$#@62;Handle, FileName.c_str(), i);
Icon-$#@62;SaveToFile(SaveDialog1-$#@62;FileName+(AnsiString)i+".ico");

}

}
//----------------------------------------------------------------
void __fastcall TForm1::Button4Click(TObject *Sender)
{

Close();

}
//----------------------------------------------------------------
void __fastcall TForm1::ScrollBar1Change(TObject *Sender)
{

Edit2-$#@62;Text=ScrollBar1-$#@62;Position+1;
Icon-$#@62;Handle = ExtractIcon(Form1-$#@62;Handle, FileName.c_str(),ScrollBar1-$#@62;Position);
Image1-$#@62;Picture-$#@62;Icon=Icon;

}
//----------------------------------------------------------------

判斷驅動器的類型


  使用API函數GetDriveType能判斷一個驅動器的類型,該函數返回一個int型的值,當返回值爲2時,是軟盤;爲3時,是硬盤;爲4時,是網絡映射盤;爲5時,是光驅;爲6時,是 RAM 磁盤;爲其它值時,是非法的盤符。這個API函數包含在winbase.h頭文件中,首先在程序頭部加上語句:

include $#@60;winbase.h$#@62;

包含頭文件,然後在程序中加入以下代碼就可以判斷驅動器的類型:

int drv;
//這裏的"C://"爲要判斷的盤符
drv=GetDriveType("C://");
switch (drv) //判斷drv的值
{
case 2 : //DRIVE_REMOVABLE

ShowMessage("軟盤");
break;

case 3 : //DRIVE_FIXED

ShowMessage("硬盤");
break;

case 4 : //DRIVE_REMOTE

ShowMessage("網絡映射盤");
break;

case 5 : //DRIVE_CDROM

ShowMessage("光驅");
break;

case 6 : //DRIVE_RAMDISK

ShowMessage("RAM 磁盤");
break;

default :

ShowMessage("這個磁盤不存在!");
break;

}

注:case語句後的數值也可以用註釋後的常數替換。如2可用常數 DRIVE_REMOVABLE 來替換。

api技巧集(七)

窗口最小化、最大化和恢復

  通過調用API函數ShowWindow可以控制指定窗口的狀態,如將窗口最小化、最大化或者是恢復原來的狀態,等等。

  雖然通過窗口標題欄上的控制按鈕也可以將窗口最小化、最大化或者是恢復,但ShowWindow函數能實現更多的功能,又如隱藏窗口、將窗口最小化到桌面等,這些是標準的控制按鈕所做不到的。

  下面介紹一個ShowWindow函數的例子。這個例子演示瞭如何將一個窗口最小化到桌面或最小化到任務欄和最大化、恢復窗口原始狀態。

  首先,在C++ Builder中新建一個工程,爲了方便演示,工程需要兩個窗口。添加第二個窗口Form2的方法是:選擇“File”菜單下的“New Form”。添加了新窗口後,選擇“File”菜單下的“Include Unit Hdr...”包含窗口Form2的頭文件“Unit2.h”,或是直接在Form1的代碼編輯窗口的頭部加上“#include "Unit2.h"”語句。然後在Form1上放上四個按鈕,它們的Caption屬性分別爲“最大化”、“最小化到桌面”、“恢復”和“最小化到任務欄並恢復”。

  接着,雙擊窗件Form1,在它的OnCreate事件中加入:

void __fastcall TForm1::FormCreate(TObject *Sender)

{

  //設置Form1爲頂層窗口

Form1-$#@62;FormStyle=fsStayOnTop;

}

  雙擊按鈕Button1,在它的OnClick事件中加入:

void __fastcall TForm1::Button1Click(TObject *Sender)

{

  //最大化

ShowWindow(Form2-$#@62;Handle, SW_MAXIMIZE);

}

雙擊按鈕Button2,在它的OnClick事件中加入:


void __fastcall TForm1::Button2Click(TObject *Sender)

{ //最小化到桌面

ShowWindow(Form2-$#@62;Handle, SW_MINIMIZE);

}

雙擊按鈕Button3,在它的OnClick事件中加入:

void __fastcall TForm1::Button3Click(TObject *Sender)

{

  //恢復最小化

ShowWindow(Form2-$#@62;Handle, SW_RESTORE);

}

{{秪峈最唗郔苤趙恄魊蛹鞶 酸傿蒚鰽蔑棠奴 埶朒鍤◆ 芼硌斯譬 賱撥霾蝌阭棠 utton4腔OnClick岈璃笢〔峈賸?虴別載隴珆ㄛ笢潔樓?珨跺晊奀腔測鎢ㄩ

void __fastcall TForm1::Button4Click(TObject *Sender)

{

  //最小化到任務欄

ShowWindow(Application-$#@62;Handle, SW_MINIMIZE);

  //延時1秒

Sleep(1000);

  //恢復最小化

ShowWindow(Application-$#@62;Handle, SW_RESTORE);

}

  最後,編譯運行程序。

  獲取磁盤序列號、卷標和文件系統類型

  使用API函數GetVolumeInformation,可以獲取一個磁盤的有關信息,如磁盤的序列號、卷標、文件系統類型。有些軟件就是利用磁盤的序列號來加密的。

  需要獲取磁盤信息的時候,加入下面的代碼就可以了:

  //定義長度爲255的卷標字符串變量緩衝區:

AnsiString VolumeName=AnsiString::StringOfChar(" ", 255);

  //序列號

unsigned long SerialNumber;

  //定義長度爲20的文件系統類型字符串緩衝區

AnsiString SystemName = AnsiString::StringOfChar(" ",20);

  //獲取磁盤信息

GetVolumeInformation("C://", VolumeName.c_str(), 255, &SerialNumber, 0, 0, SystemName.c_str(), 20);

ShowMessage("C盤的卷標:" + Trim(VolumeName));

ShowMessage("C盤的序列號:" + IntToStr(SerialNumber));

ShowMessage("C盤的文件系統類型:" + Trim(SystemName));
  屏幕放大鏡

  你一定用過Windows98自帶的那個屏幕放大鏡吧,你想不想自已做一個呢?其它,這個程序的關鍵是使用了API函數StretchBlt。

  調用API函數StretchBlt可以把一個設備中指定大小的位圖從拷貝到另一個設備,在拷貝的過程中,還可以根據需要來縮放位圖。

  下面是它的原型和參數說明:

BOOL StretchBlt

(

HDC hdcDest, //目標設備句柄

int nXOriginDest, //目標矩形左上角的X座標

int nYOriginDest, //目標矩形左上角的Y座標

int nWidthDest, //目標矩形的寬度

int nHeightDest, //目標矩形的高度

HDC hdcSrc, //源設備句柄

int nXOriginSrc, //源矩形左上角的X座標

int nYOriginSrc, //源矩形左上角的Y座標

int nWidthSrc, //源矩形的寬度

int nHeightSrc, //源矩形的高度

DWORD dwRop //光柵運算操作

);

  StretchBlt函數的頭文件爲“wingdi.h”。其中,它的dwRop參數有15種操作,最常用的就是拷貝運算SRCCOPY了。當源設備和目標設備指定的矩形大小不相等時,函數會根據源矩形和目標矩形的大小比例對位圖進行放大或縮小操作後,拷貝到目標設備中。

  下面就是一個把屏幕上左上角座標爲0x0、寬和高都爲100的矩形位圖縮小2倍後拷貝到圖片控件Image1中的例子:

StretchBlt(Image1-$#@62;Canvas-$#@62;Handle, 0, 0, 50, 50, GetDC(0), 0, 0, 100, 100, SRCCOPY);

  這句代碼的GetDC(0)語句爲取得桌面設備的句柄。

  如果不斷地使用上面那句代碼,把屏幕縮小放到Image1中,這就成一個“屏幕縮小鏡”了。當然,縮小屏幕並沒有什麼實際的用處,我們只要把它改一下就可以做成“屏幕放大鏡”了。

  要做這個“屏幕放大鏡”,首先要運行Borland C Builder,在窗體Form1上放上一個圖片控件Image1和一個時間控件Timer1。

雙擊窗體Form1,在它的OnCreate事件中加入代碼:

void __fastcall TForm1::FormCreate(TObject *Sender)

{

Image1-$#@62;Width=200;

Image1-$#@62;Height=200;

Timer1-$#@62;Interval=10;
  //設置頂層窗口

SetWindowPos( Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE||SWP_NOSIZE);

}

  雙擊時間控件Timer1,在它的OnTimer事件中加入以下代碼:

void __fastcall TForm1::Timer1Timer(TObject *Sender)

{

int x,y;

POINT CurPos;

  //取得鼠標當前座標

GetCursorPos(&CurPos);

  //保證拷貝的圖象不在屏幕外

if(CurPos.x $#@62;Screen-$#@62;Width - 100)

x=Screen-$#@62;Width - 100;

else if(CurPos.x $#@60;50)

x=0;

else

x=CurPos.x-50;

if(CurPos.y $#@62;Screen-$#@62;Height-100)

y=Screen-$#@62;Height-100;

else if(CurPos.y $#@60;50)

y=0;

else

y=CurPos.y-50;

Caption="座標:" + IntToStr(CurPos.x) + "," + IntToStr(CurPos.y);

Image1-$#@62;Canvas-$#@62;FillRect(Rect(0,0,200,200));
  //拷貝放大圖象

StretchBlt(Image1-$#@62;Canvas-$#@62;Handle, 0, 0, 200, 200, GetDC(0), x, y, 100, 100, SRCCOPY);

}

  代碼輸入完了,按F9或點擊運行按鈕運行程序。怎麼樣?和Windows自帶的那個差不多吧!

  需要注意的是:C++ Builder並象VB那樣圖片控件可以是非持久性的,在C++ Builder中,並不能直接不斷地調用StretchBlt函數來得到連貫的圖象,而是要先使用圖片控件的FillRect方法填充圖片框(相當於清空圖片框),再調用StretchBlt函數才行。

  時間的延遲

  延遲在程序設計中非常有意義!比如,程序啓動時的等待畫面,又或者你需要等待一個過程的完成才能運行程序下面的代碼,這時就要使用到時間的延遲了。

  但是在很多編程語言中一般都沒有現成的延遲函數。在Dos的C時代,當程序需要延遲時,有不少人使用的是for循環:

for(int i=0;i$#@60;10000;i++);

  到現在也可能還有人在用吧。到了Win32時代,在系統的API函數庫裏已經提供有時間延遲的函數了,它就是Sleep函數。當然,在Windows編程中,你也可以使用Timer控件,但使用Sleep函數更方便、快捷。我們只需簡單的調用一下Sleep函數,就可以實現時間的延遲。

  Sleep函數只有一個參數cMilliseconds,用來指定需要延遲的時間,它的單位是毫秒。讓我們看下面的例子,請在一個按鈕的單擊(OnClick)事件中加入下面的代碼:

Sleep(3000);//延遲三秒

ShowMessage("本對話框已經延遲了三秒!");

  這個例子演示了一個延時的對話框,單擊了該按鈕,本應立即彈出的對話框延遲了三秒鐘的時間才彈出。

 

轉自 http://www.xici.net/ 西祠衚衕

發佈了19 篇原創文章 · 獲贊 10 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章