'Windows API'에 해당되는 글 4건

  1. 2008.09.19 윈도우를 투명하게!!! 1
  2. 2008.09.05 Windows Power management API - PBT_APMPOWERSTATUSCHANGE Event 1
  3. 2008.08.11 GetMessage() 와 PeekMessage() 1
  4. 2008.07.24 키보드 키의 상태값을 알아오기
2008. 9. 19. 11:14

윈도우를 투명하게!!!


프로그램을 하다보면 이런 저런 황당한 요구사항을 많이 겪게 된다. 가령 현재 실행되는 윈도우를 약간 투명하게 해서 그 프로그램 아래 있는 다른 것들을 볼 수 있도록 해달라는..

대충 알송의 데스크톱 가사보기와 같은 그런 걸 원하는 모양이다.

아.. 저런건 어찌 만들지...-_- 하면서 이리 저리 검색을 해본 결과.. 가능한 것이었고.. 간단한 테스트 프로그램을 통해 원하는 결과를 대충 얻어 포스팅 한다.

현재 사용하는 툴은 VS2005이고, Windows API로 작성이 되었다.

투명한 윈도우를 만들기 위해서는 SetLayeredWindowAttributes() 라는 함수를 사용해야 한다. 이녀석은 Layered Window 의 투명도 / 색상 등을 설정할 수 있는 함수이다.
BOOL SetLayeredWindowAttributes(  
    HWND hwnd,            - 투명하게 처리할 윈도우의 핸들
    COLORREF crKey,    - 대상 윈도우의 투명하게 처리할 색상(COLORREF)값
    BYTE bAlpha,           - 대상 윈도우의 투명도를 설정 ( 0 ~ 255)
    DWORD dwFlags       -  LWA_COLORKEY, LWA_ALPHA 등의 옵션
);

이 함수를 사용하기 위해서는 'Windows 2000 이상의 운영체제'여야 하고, 'Windows.h 헤더파일을 포함'하고 'User32.lib 라는 라이브러리를 사용'해야 한다. 뭐 요즘 사용하는 운영체제는 거의 XP 이상일 것이고, 윈도우즈 프로그램을 하면 기본적으로 Windows.h 와 User32.lib는 사용할 것이니.. 별로 신경을 안써도 될 듯하다.

추가로 신경을 써야 할 부분은 #include <windows.h> 위에 추가시켜 줘야 하는 부분이 있다는 것이다.

 #define WINVER 0x500  
 #define _WIN32_WINNT 0x500 
 #include <windows.h>

위와 같이 처리해주는 부분이 있어야 하는 이유는... 윈도우즈 프로그램에서는 윈도우즈 버전에 따라 사용 혹은 사용할 수 없는 함수들이 있다고 한다. Winodws 2000 이상에서만 사용되는 함수를 사용하기 위해서는 위와같이 처리해주어야 한다. 그렇지 않으면 에러가 발생할지도... ^^;

CreateWindowsEX()를 사용해 윈도우즈를 생성할 때 WS_EX_LAYERED라는 속성을 넣어준다.
아니면, 윈도우즈 생성시기가 아닌 나중에라도

SetWindowLong ( hDlg, GWL_EXSTYLE, GetWindowLong(hDlg, GWL_EXSTYLE) | WS_EX_LAYERED );
를 쓰던지 해서 이녀석을 넣어줘야 정상적으로 투명 윈도우를 만들어낼 수 있다.

마지막으로 SetLayeredWindowAttributes() 함수를 사용한다. 이 함수의 네번 째 인자는 LWA_ALPHA를 사용하고, 세번째 인자의 값을 조절하면서 투명도를 조절하면 된다.

SetLayeredWindowAttributes(hDlg, 0, 100, LWA_ALPHA);
이렇게 처리를 해주면...
사용자 삽입 이미지

사용자 삽입 이미지
이렇게 변한다고... ㅋ


음.. 조금 신기해 주는데.. ㅋㅋ

2008. 9. 5. 16:10

Windows Power management API - PBT_APMPOWERSTATUSCHANGE Event


Windows System에서 전력관리(Power management)를 위해 사용되는 API들이 있다. 지금 보게 될 'PBT_APMPOWERSTATUSCHANGE '라는 녀석도 그에 속한다.

'PBT_APMPOWERSTATUSCHANGE'는 사용하는 기계의 전원상태(power status)의 변화가 생길때 Windows system에서 어플리케이션에 전달(broadcast)되는 event 이다.
예를들어 노트북에서 AC전원을 사용하다가 전원코드를 뽑아서 배터리의 전원을 사용한다던지, 아님 그 반대든지.. 뭐 그런경우 시스템에서는 현재 사용하는 기계의 전원상태의 변화가 생김을 인지하고 이 이벤트를 날려준다(broadcasting).

이 이벤트는 'WM_POWERBROADCAST'라는 메시지를 통해서 어플리케이션에 전달되고, 해당하는 이벤트는 메시지의 'wParam'을 통해 전달된다.


사용방법은.. 대충 이렇다.
음.. Windows API를 예로들어 설명한다.(다른건 할줄몰라서.. 이것도.. 잘은.. -_-)

LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
    HDC hdc;

    switch (iMessage) {
        ...
        case WM_POWERBROADCAST:
            switch(wParam){
            case PBT_APMPOWERSTATUSCHANGE:
                MessageBox(hWnd, TEXT("test"), TEXT("test"), MB_OK);
                return 0;
            }
        return 0;
        ...
    }
    return(DefWindowProc(hWnd,iMessage,wParam,lParam));
}


추가로 WM_POWERBROADCAST 메시지의 wParam은 다음과 같은 것들이 있다.

Event

Meaning

PBT_APMBATTERYLOW

Battery power is low

PBT_APMOEMEVENT

OEM-defined event occurred

PBT_APMPOWERSTATUSCHANGE

Power status has changed

PBT_APMQUERYSUSPEND

Request for permission to suspend

PBT_APMQUERYSUSPENDFAILED

Suspension request denied

PBT_APMRESUMEAUTOMATIC

Operation resuming automatically after event

PBT_APMRESUMECRITICAL

Operation resuming after critical suspension

PBT_APMRESUMESUSPEND

Operation resuming after suspension

PBT_APMSUSPEND

System is suspending operation


여기를 참고하면 될 듯 하다.
WM_POWERBROADCAST : http://msdn.microsoft.com/en-us/library/aa373247.aspx
PBT_APMPOWERSTATUSCHANGE : http://msdn.microsoft.com/en-us/library/aa372715(VS.85).aspx

2008. 8. 11. 15:18

GetMessage() 와 PeekMessage()



Windows API 프로그래밍에서 GetMessage()PeekMessage() 는 메시지 루프에서 사용되는 API이다. 둘다 메시지 큐에서 메시지를 가져오는 역할을 하는데.. 두 API에 약간의 차이는 있다.

BOOL GetMessage ( LPMSG lpMsg,
                            HWND hWnd,
                            UINT wMsgFilterMin,
                            UINT wMsgFilterMax)
GetMessage() 는 메시지 루프... 스레드 메시지 큐에서 메시지를 읽은 후 읽은 메시지를 큐에서 제거한다.

BOOL PeekMessage ( LPMSG lpMsg,
                              HWND hWnd,
                              UINT wMsgFilterMin,
                              UINT wMsgFilterMax,
                              UINT wRemoveMsg)

PeekMessage() 는 GetMessage() 와 마찬가지로 메시지 큐에서 메시지를 읽는 다 메시지의 범위를 줄 수 있는 기능도 GetMessage() 와 동일하다. 하지만, PeekMessage() 는 GetMessage() 와는 달리 읽은 메시지를 무조건 저거하지 않으며 큐가 비어있을 경우 대기하지 않고 바로 리턴한다는 점이 다르다. 따라서 이 함수는 메시지를 읽지 않고 단순히 메시지가 있는지 확인만 할 수 있으며, 이런 특성은 백그라운드 작업에 적절하다.
PeekMessage() 의 마지막 인자를 PM_NOREMOVE로 지정을 하면 큐에서 메시지를 없애지 않고 내용을 볼 수 있다. PM_REMOVE로 지정을 하면 GetMessage() 처럼 큐에서 메시지를 없앤다.


간단히 말해 GetMessage() 함수는 큐에 메시지를 받을 때 까지 복귀하지 않고 루프를 돌면서 대기하는 상태이지만, PeekMessage() 함수는 큐에 메시지가 없는 경우에도 즉석에서 제어를 돌려주고, 다른 일을 할 수 있다는 것이다.


출처 : http://winapi.co.kr

2008. 7. 24. 15:47

키보드 키의 상태값을 알아오기



키보드 관련된 작업을 Windows XP 에서 프로그래밍을 하고 있는 중이다.
아... 'OS' 관련 작업하다가 갑자기 몇년만에 'Windows Application' 작업을 하려니 적응이 안된다.
어찌 됐건 해야 하는 일이므로.. 이리 저리 자료를 찾고 있는 중이긴 하지만.. 빡쎄다... -_-

키보드 키의 상태값을 받아오는 방법에 대해 찾고 있던 도중 'Windows API'에 좋은 함수가 있다는 걸 알아버렸다.ㅋ

GetKeyState() 라는 함수인데.. 이녀석은 키가 눌린 상태인지.. 그리고 키가 토글상태가 무엇인지를 알아낼때 사용되는 함수이다.
쉽게 말해서 NumLock키의 경우 토글된 상태이면 NumLock LED에 불이 들어온다. 토글된 상태가 아니면 NumLock LED의 불이 꺼진다. 이런 상태를 받아오는 것이다.
이 함수는 다음과 같다.
SHORT GetKeyState(      
    int nVirtKey
);
parameter는 상태를 알고자하는 키의 Virtual Key값을 넣으면 되고, Return 되는 값은 상태를 알고자하는 Virtual Key값의 상태를 리턴한다.

쉽게 예를 들면, 음.. NumLock 키가 눌려져 있는지를 보려면.. 다음과 같이 해주면 될 것이다.
 
       int numlock_status = 0;

        ....

        if((::GetKeyState(VK_NUMLOCK) & 0x80000 ) > 0)
            numlock_status = 1;
        else
            numlock_status = 0;

이와 유사한 기능을 가지고 있는 함수로.. GetAsyncKeyState() 라는 함수가 있다.

MSDN에는 현재 하드웨어(키보드)의 상태값을 알아내고자 한다면.. GetAsyncKeyState() 를 사용하라고 한다.
GetKeyState() 는 메시지큐에 저장된 메시지에 따라 값이 변하기 때문이다. 메시지큐에 처리되지 않은 CTRL 키가 눌렸다는 메시지가 쌓여있을 때, 사용자가 CTRL 키를 더이상 누르지 않고 있다면... GetAsyncKeyState() 는 "키가 눌려있지 않음"을 반환하고, GetKeyState() 는 "키가 눌렸음"을 반환하기 때문이다.
(참고 : 러브러브 님의 블로그)