顯示具有 Win32 標籤的文章。 顯示所有文章
顯示具有 Win32 標籤的文章。 顯示所有文章

2014年4月13日 星期日

Remove secure warnings (_CRT_SECURE_NO_WARNINGS) in Visual Studio 2012

Right click Project name then ,
"Properties"->"Configuration properties"->"C/C++"->"Preprocessor"->"Preprocessor definitions".

2013年5月25日 星期六

[Win32] 開關螢幕及鎖定(Screen On/Off and Lock)

開啟及關閉螢幕(Screen On/Off)
我們利用SendMessage來廣播WM_SYSCOMMAND訊息給所有視窗(windows),
然後代入SC_MONITORPOWER這個參數來設定顯示狀態,設定值如下面描述。

SC_MONITORPOWER
  • -1 (開啟螢幕)
  • 1  (讓螢幕處於低耗電量)
  • 2  (關閉螢幕)

下面是程式碼片段,注意最後一個參數的設定,代表不同功能。
void screenOff()
{
    SendMessage(HWND_BROADCAST, WM_SYSCOMMAND, SC_MONITORPOWER,(LPARAM)2);
}

void screenOn()
{
    SendMessage(HWND_BROADCAST, WM_SYSCOMMAND, SC_MONITORPOWER,(LPARAM)-1);
}

void screenLowPower()
{
    SendMessage(HWND_BROADCAST, WM_SYSCOMMAND, SC_MONITORPOWER,(LPARAM)1);
}

鎖定(Lock)
鎖定的功能就和按下 Ctrl+Alt+Del,然後在選擇"鎖定"一樣
void lock()
{
    LockWorkStation();
}

[Win32] 關機及重開機(shutdown and restart)

關機和重開機(shutdown and restart)首先要先調高你的程序(process)到可以關機及重開機的權限,
然後在利用這個InitiateSystemShutdown API來達到關機和重開的功能。

我們來介紹一下InitiateSystemShutdown這個API,依照MSDN的描述,

BOOL WINAPI InitiateSystemShutdown(
_In_opt_ LPTSTR lpMachineName,
_In_opt_ LPTSTR lpMessage,
_In_ DWORD dwTimeout,
_In_ BOOL bForceAppsClosed,
_In_ BOOL bRebootAfterShutdown
);

lpMachineName [in, optional]: 如果您想要關閉另一台電腦,在這裡則要輸入那台電腦的網路名稱;反之如果設成NULL,則表示關閉當下這台電腦。
lpMessage [in, optional]: 這裡是用來設定關機對話框的內容描述。
dwTimeout [in]: 搭配第二個參數,用來設定對話框的停留的時間,如果設定成零的話,就不會顯示對話框,然後直接關機。
bForceAppsClosed [in]:如果為TRUE,應用程式不會被存檔,即會強迫馬上關機,所以資料有可能會遺失。
如果為FALSE,系統會顯示一個對話框,來引導使用者去關閉其它已開啟的應用程式。
bRebootAfterShutdown [in]:如果為TRUE為重開的意思,如果為FALSE則是關機。

程式碼如下:
void shutdown()
{
 HANDLE hToken; 
 TOKEN_PRIVILEGES tkp; 
 BOOL fResult; 

 // Get the current process token handle so we can get shutdown privilege.
 if (!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
  printf("OpenProcessToken failed.");

 // Get the LUID for shutdown privilege.
 LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME,&tkp.Privileges[0].Luid);
 tkp.PrivilegeCount = 1; // one privilege to set
 tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

 // Get shutdown privilege for this process.
 AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES) NULL, 0);

 if (GetLastError() != ERROR_SUCCESS)
  printf("AdjustTokenPrivileges enable failed.");

 fResult = InitiateSystemShutdown( NULL, NULL, 0, FALSE, FALSE); //最後一個參數,TRUE表示重開機,FASLE表示關機
 if (!fResult)
 {
  printf("InitiateSystemShutdown failed.");
 }

 // Disable shutdown privilege.
 tkp.Privileges[0].Attributes = 0;
 AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,(PTOKEN_PRIVILEGES) NULL, 0);

 if (GetLastError() != ERROR_SUCCESS)
 {
  printf("AdjustTokenPrivileges disable failed.");
 } 
}

[Win32] 休眠及睡眠(hibernate and suspend)

剛好用到幾個電源管理的APIs,先簡單介紹一下休眠及睡眠。
休眠和睡眠有什麼不同呢?

睡眠(suspend)會讓電腦處於一個低耗電量的模式,但當電源被用光時,
電腦還是會關機的,所以沒有被儲存的資料還是會遺失。

休眠(hibernate)則會將電腦當下的狀態存到硬碟裡,然後power off;
當喚醒時(resume),則會回存power off前狀態到記憶體裡(RAM)。
舉個例子,當你開啟了office word和excel,然後按下休眠,再喚醒時,依然會看到word和excel;
反之,如果是重開機,就看不到啦。

實作上會用到一個API,SetSuspendState
BOOLEAN WINAPI SetSuspendState(
_In_ BOOLEAN Hibernate,
_In_ BOOLEAN ForceCritical,
_In_ BOOLEAN DisableWakeEvent
);

Hibernate [in] : 如果是TRUE,系統將進入hibernates;反之則是suspended。
ForceCritical [in] : 如果是TRUE,系統則立刻suspend;
反之系統會先廣播一個PBT_APMQUERYSUSPEND事件給每一個應用程式,請求要suspend的權限。
DisableWakeEvent [in] : 如果是TRUE,系統將關掉所有wake event,反之wake events得是開啟的。

程式碼如下:
void suspend()
{
   //If the first parameter is TRUE, the system hibernates. 
  //If the parameter is FALSE, the system is suspended.
   SetSuspendState(FALSE, TRUE, FALSE); 
}

void hibernation()
{
   SetSuspendState(TRUE, TRUE, FALSE); 
}

2013年4月2日 星期二

[Win32] 高精確度計算程式執行時間 (QueryPerformanceCounter)

舉例來說,我們想來計算一個函式(function)執行所花的時間

LARGE_INTEGER g_lStartTime
LARGE_INTEGER g_lEndTime;
LARGE_INTEGER g_lFreq;

void sample()

{

 //取得目前 CPU frequency

 QueryPerformanceFrequency( &g_lFreq);

 // 取得目前開始時間

 QueryPerformanceCounter( &g_lStartTime);

//你的程式

 for ( i = 0 ; i < 5000 ; i++)

       i = i+1;

//取得執行後的時間

QueryPerformanceCounter( &g_lEndTime );

//計算一共花了多少時間

double dElapsedTime = (g_lEndTime.QuadPart - g_lStartTime.QuadPart) * 1000.0 / g_lFreq.QuadPart;

 //列印出來

printf( "Elapsed time = %lf millisecond\n", dElapsedTime );

}