728x90
반응형

윈도우 핸들

 

.NET API WINDOW

 

.NET API WINDOW

윈도우 생성 단계 아래 링크에 있는 WinMain 함수에서 하는 가장 중요한 일은 윈도우를 생성하는 일입니다. Console Application은 콘솔창을 통해서 사용자로 부터 입력을 받고 출력물을 내보냅니다. 하

kkunja.tistory.com

지난 예제에서 보았던 ShowWindow() 함수는 윈도우를 화면에 다양한 형태로 출력할 때 사용합니다. MoveWindow() 함수는 윈도우를 이동할 때 사용하며 GetWindowRect() 함수는 윈도우의 위치와 크기를 얻을 때 사용합니다.

BOOL ShowWindow(HWND hWnd, int nCmdShow)
BOOL MoveWindow(HWND hWnd, int X, int Y, int nWidth, int nHeight,
BOOL bRepaint);
BOOL GetWindowRect(HWND hwnd, LPRECT lpRect);

이 외 다수의 API 함수들은 객체를 제어하기 위한 목적으로 제공되며, 위에서 제시한 함수들은 그 중 윈도우를 제어하기 위한 목적의 함수입니다. 따라서 첫번째 인자로 제어할 대상의 윈도우 핸들을 요구합니다.

 

따라서 윈도우 핸들은 해당 윈도우를 제어하기 위한 필수적 정보이며, 이를 알고 있다면 다양한 API 함수를 사용하여 원하는 명령어를 내릴 수 있습니다.

 

윈도우 핸들 얻기

HWND FindWindow(LPCTSTR lpCalssName, LPCTSTR lpWindowName);

위의 함수를 사용하면 윈도우 핸들을 얻을 수 있습니다. 

1번째 인자로 윈도우를 만든 윈도우 클래스 이름, 2번째 인자로 윈도우의 캡션바에 있는 문자열을 지정합니다. 만약 윈도우 클래스 이름을 모르거나 캡션바가 없는 경우라면 해당 항목을 0을 지정하면 됩니다.

#include <windows.h>
#include <tchar.h>
int WINAPI _tWinMain(HINSTANCE hInst, HINSTANCE hPrev, LPTSTR lpCmdLine, int nShowCmd)
{
    HWND hwnd = FindWindow(0, _TEXT("계산기"));
    if( hwnd == 0 ) {
    MessageBox(0, _TEXT("계산기 핸들을 얻을 수 없습니다."),
                  _TEXT("알림"), MB_OK|MB_ICONERROR);
               return 0;
  }
  else {
         TCHAR temp[20];
         wsprintf(temp, _TEXT("계산기 핸들 : %d"), hwnd);
         MessageBox(0, temp, _TEXT("알림"), MB_OK);
 }
 return 0;
}

윈도우 핸들을 얻는 예제입니다.

 

윈도우 제어하기

#include <windows.h>
#include <tchar.h>

int WINAPI _tWinMain(HINSTANCE hInst, HINSTANCE hPrev, LPTSTR lpCmdLine, int nShowCmd)
{
     HWND hwnd = FindWindow(0, _TEXT("계산기"));
     //계산기 클래스 이름 및 Rect 얻기
     TCHAR name[60];
     RECT rcCalc;
     GetClassName(hwnd, name, sizeof(name));
     GetWindowRect(hwnd, &rcCalc);
     
     //정보 출력
     TCHAR info[256];
     wsprintf(info, _TEXT("클래스 명 : %s\n위치 : %d,%d ~ %d,%d"), name,
     rcCalc.left, rcCalc.top, rcCalc.right, rcCalc.bottom);
     MessageBox(0, info,TEXT("계산기 정보"), MB_OK);
     
     //계산기 이동하기
     MoveWindow(hwnd, 10, 10, rcCalc.right - rcCalc.left, rcCalc.bottom -
     rcCalc.top, TRUE);
     
     //계산기 숨기기
     MessageBox(0, _TEXT("계산기"),TEXT("계산기 숨기기"), MB_OK);
     ShowWindow(hwnd, SW_HIDE);
     
     //계산기 보이기
     MessageBox(0, _TEXT("계산기"),TEXT("계산기 보이기"), MB_OK);
     ShowWindow(hwnd, SW_SHOW);
     
     //계산기 종료하기
     MessageBox(0, _TEXT("계산기"),TEXT("계산기 종료하기"), MB_OK);
     SendMessage(hwnd, WM_CLOSE, 0, 0);
     return 0;
}

SendMessage 함수는 1번째 인자에 전달된 윈도우에 명령을 내릴 수 있는 함수이며 WM_CLOSE 메시지는 종료 메시지 입니다.

 

윈도우 클래스 정보

 

윈도우 클래스는 3가지 종류가 있습니다.

시스템 전역 클래스(System global class)

  • 운영체제가 부팅될 때 등록되며 주로 컨트롤을 만들 때 사용됩니다.
  • Button, edit, scrollbar, listbox 등이 그 예이며, 따라서 버튼 윈도우를 만들고 싶다면 등록된 button 이라는 클래스명으로 참조해서 생성하면 됩니다.

응용 프로그램 전역 클래스(Application global class)

  • 주로 DLL에 등록되며 다른 프로그램에서 사용 될 수 있습니다.
  • 공통 컨트롤들이 이에 해당되며, 해당 클래스정보는 comctl32.dll 에 저장되어 있습니다.

응용 프로그램 로컬 클래스(Application local class)

  • 응용 프로그램 자신이 메인 윈도우나 차일드 또는 커스텀 컨트롤을 만들기 위해 프로그램 상단에 등록하는 클래스이며 해당 프로그램이 종료되면 윈도우 클래스도 같이 파괴됩니다.
  • 등록한 곳에서만 사용할 수 있습니다.

SetClassLong

 

WINDCLASS 구조체의 값은 윈도우 클래스를 등록할 때 정해지지만 등록된 후에도 수정할 수 있습니다.

// 32bit 전용 함수 : 기존 사용된 함수
DWORD GetClassLong(HWND hWnd, int nIndex);
DWORD SetClassLong(HWND hWnd, int nIndex, LONG dwNewLong);
// 64bit 전용 지원 함수 : 대체된 함수
LONG_PTR GetClassLongPtr(HWND hWnd, int nIndex);
LONG_PTR SetClassLongPtr(HWND hWnd, int nIndex, LONG_PTR dwNewLong);

위의 함수들은 실행 중 윈도우 클래스 정보를 획득하거나 변경할 때 사용되는 함수들입니다. 과거에는 윗 단의 함수들이 사용되었지만 64비트를 지원하는 아래의 함수로 완전히 대체되었습니다.

 

int WINAPI _tWinMain(HINSTANCE hInst, HINSTANCE hPrev, LPTSTR lpCmdLine, int nShowCmd)
{
       MyRegisterClass(hInst);
       HWND hwnd = InitInstance (hInst, nShowCmd);
       if (hwnd == 0) { return FALSE; }
       
       //실시간 클래스 정보 수정
       MessageBox(0, TEXT("실시간 정보 수정"),TEXT("First"), MB_OK);
       SetClassLongPtr(hwnd, GCLP_HBRBACKGROUND, (LONG)GetStockObject(DKGRAY_BRUSH));
       InvalidateRect(hwnd, NULL, TRUE);
       MessageBox(0, TEXT("Hello,API"),TEXT("First"), MB_OK);
       
       //실시간 클래스 정보 획득
       TCHAR temp[126];
       DWORD flag = GetClassLongPtr(hwnd, GCLP_HBRBACKGROUND);
       wsprintf(temp, _TEXT("R : %d, G : %d : B : %d"), GetRValue(flag), GetG
       Value(flag), GetBValue(flag));
       MessageBox(0, temp, TEXT("획득정보"), MB_OK);
       return 0;
}

위의 예제는 윈도우 배경색을 실시간 변경하고 변경된 정보를 확인해 보는 예제입니다.

 

윈도우 객체

 

윈도우 객체는 운영체제가 하나의 윈도우를 관리하기 위해 생성하는 데이터 구조체입니다. CreateWindow() 함수로 윈도우를 만들 때 생성되며 설정했던 윈도우의 속성들을 실행중에 조사하거나 변경하고자 할 때는 다음 두 함수를 사용합니다.

 

// 32bit 전용 함수 : 기존 사용된 함수
LONG GetWindowLong(HWND hWnd, int nIndex);
DWORD SetWindowLong(HWND hWnd, int nIndex, LONG dwNewLong);
// 64bit 전용 지원 함수 : 대체된 함수
LONG_PTR GetWindowLongPtr(HWND hWnd, int nIndex);
LONG_PTR SetWindowLongPtr(HWND hWnd, int nIndex, LONG_PTR dwNewLong);

윈도우 오브젝트

CreateWindow() 함수는 윈도우 오브젝트를 생성하고 ShowWindow() 함수는 생성된 윈도우 오브젝트 정보를 바탕으로 화면에 윈도우를 출력해줍니다.

 

GetWindowLongPtr() 함수는 지정된 윈도우 오브젝트에서 원하는 정보를 얻을 수 있고, SetWindowLongPtr() 함수는 저장된 오브젝트 정보를 수정할 수 있습니다.

 

윈도우 오브젝트 인자 정보는 아래와 같습니다.

인수 설명
GWL_EXSTYLE 확장 스타일
GWL_STYLE 윈도우 스타일
GWLP_WNDPROC 윈도우 프로시저 번지
GWLP_HINSTANCE 인스턴스 핸들
GWLP_HWNDPARENT 부모 윈도우의 핸들
GWLP_ID ID
GWLP_USERDATA 윈도우와 관련된 사용자 데이터
GWLP_DLGPROC 대화상자 프로시저의 주소
GWLP_MSGRESULT 대화상자 프로시저의 리턴값
GWLP_USER 사용자 데이터

 

BOOL fun_ModifyStylpe(HWND hwnd, LONG_PTR Add, LONG_PTR Remove, BOOL bRedraw)
{
        BOOL bFlag = FALSE;
        LONG_PTR style = GetWindowLongPtr(hwnd, GWL_STYLE);
        style |= Add;
        style &= ~Remove;
        bFlag = (BOOL)SetWindowLongPtr(hwnd, GWL_STYLE, style);
        if( bFlag && bRedraw )
        SetWindowPos(hwnd, 0, 0, 0, 0, 0,SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_DRAWFRAME);
        return bFlag;
}

int WINAPI _tWinMain(HINSTANCE hInst, HINSTANCE hPrev, LPTSTR lpCmdLine, int nShowCmd)
{
       MyRegisterClass(hInst);
       HWND hwnd = InitInstance (hInst, nShowCmd);
       if (hwnd == 0) {
       return FALSE;
       }
       // 실시간 윈도우 객체 정보 수정
       HWND hWnd = FindWindow(0, _TEXT("계산기"));
       fun_ModifyStylpe(hWnd,WS_THICKFRAME, WS_SYSMENU, TRUE);
       MessageBox(0, TEXT(""), TEXT(""), MB_OK);
       return 0;
}

SetWindowPos() 함수는 윈도우의 Z-order, 위치, 크기 정보를 변경할 수 있는 함수입니다.

1번째 인자는 대상 윈도우 핸들, 2,3번째 인자는 위치, 4,5번째 인자는 폭과 높이, 6번째 인자는 실제 변경여부를 flag 연산으로 설정하게 됩니다. 예제에서는 위치와 폭과 높이, Z-order 값은 사용하지 않고 프레임만 다시 그리는 값으로 설정되어 있습니다.

 

만약 2번째 인자에 WS_EX_TOPMOST 값을 주면 최상위 윈도우로 설정할 수 있습니다.

728x90
반응형
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기