'실습'에 해당되는 글 25건

  1. 2007/10/10 9.18(화) 실습-1
  2. 2007/10/10 9.17(월) 실습
  3. 2007/10/10 9.13(목) 실습-3(UNICODE)
  4. 2007/10/10 9.13(목) 실습-2
  5. 2007/10/10 9.13(목) 실습-1

9.18(화) 실습-1

from Study/API 2007/10/10 16:47 view 22324
1. Caret 이동과 RegisterHotkey 등록, Animate Window 구현!!!

more..


2. DC의 생성을 클래스화 해보기

more..


3. 키상태 조사하기

more..


4. MouseMessage(WM_MOUSELEAVE를 위해선 TRACKMOUSEENVET를 설정해줘야 한다!!!)

more..



5. SendInput 으로 입력 스트림에 키보드 입력을 넣어보자.

more..


Tag | ,

9.17(월) 실습

from Study/API 2007/10/10 14:18 view 21431
// 1. 메세지 전달.
// 계산기의 Hwnd를 얻어 일반용으로 만든다.
int main()
{
    HWND hwnd = FindWindow( 0, "계산기" );
    if( hwnd == 0 )
    {
        printf( "계산기를먼저 실행\n");
        return 0;
    }
    SendMessage( hwnd, WM_COMMAND, 305, 0 );
}
// 계산기의 Hwnd를 얻어 윈도우를 닫는다.
int main()
{
    HWND hwnd = FindWindow( 0, "계산기" );

    if ( hwnd == 0 )
    {
        printf( " B를 먼저 실행.\n" );
        return 0;
    }
    //---------------------------
    int result = 0;
    result = SendMessage( hwnd, WM_CLOSE, 10, 20 );

    printf( "결과 : %d\n", result );
}


// 2. WM_CLOSE 와 WM_NCHITTEST

LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch( msg )
    {   
    case WM_CLOSE:
        {
            UINT ret = MessageBox( hwnd, "정말 종료?", "확인", MB_YESNO );

            if( ret == IDYES )
            {
                // 죽인다.. 또는 DefWindowProc()로 보내도 된다.
                DestroyWindow( hwnd );
            }
        }
        return 0;

    // WM_NCHITTEST 를 처리하는 방법
    case WM_NCHITTEST:
        {
            // 1. 먼저 DefWindowProc()으로 전달해서 hit test code를 얻는다.
            int code = DefWindowProc( hwnd, msg, wParam, lParam );

            // 2. code를 조작한다. Ctrl 누르고 끌면 창이 이동.
            if( code == HTCLIENT && GetKeyState( VK_CONTROL ) < 0 )
                code = HTCAPTION;

            // 3. code를 리턴한다. - 다음 메세지는 이 리턴값에 의해 결정된다.
            return code;
        }

    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc( hwnd, msg, wParam, lParam);
}
Tag | ,

9.13(목) 실습-3(UNICODE)

from Study/API 2007/10/10 11:33 view 20383
// 1. STL에서 사용
typedef
basic_string<char>        string;
typedef basic_string<wchar_t> wstring; int _tmain()
{
    string s;
    basic_string<char> s1 = "hello";
    basic_string<wchar_t> s2 = L"ABCD";
}

// 2. MBCS- > WBCS
int _tmain()
{
    char s[] = "ABCD가나다라";

    // 먼저 s를 wide character로 변경할 때 필요한 버퍼의 크기를 계산한다.
    size_t    sz = MultiByteToWideChar( CP_ACP, 0, s, strlen(s), 0, 0 );

    //이제 버퍼를 할당해서 사용한다.
    wchar_t* s2 = new wchar_t[sz];

    // DBCS(MBCS) -> wideChar 로 변환

    MultiByteToWideChar( CP_ACP,    // 문자열 종류( CP_ACP : ANSI 표준 문자열 )
                         0,
                         s,
                         strlen(s),
                         s2, 10 );

    setlocale( LC_ALL, "Korean" );
    wprintf( s2 );    // wide char를 출력하는 printf, C++의 wcout
    cout << endl;

    delete[] s2;
}

// 3.UNICODE
int _tmain()
{
    TCHAR s[] = _T("ABCD가나다라");

    cout << sizeof(s) << endl;
    cout << _tcslen(s) << endl;
}

// 4. UNICODE 매크로
// 매크로
#define UNICODE

#ifdef UNICODE
typedef wchar_t        TCHAR;
#define _T(x)        L##x    // ## : Token paste 두 Token을 붙인다.
#define TEXT(x)        _T(x)
#define _TEXT(x)    _T(x)
#define _tcslen        wcslen
#define _tmain        wmain

#else
typedef char        TCHAR;
#define _T(x)        x
#define _tcslen        strlen
#define _tmain        main

#endif

int _tmain(int argc, TCHAR* argv)
{
    TCHAR s[] = "ABCD가나다라";

    cout << sizeof( s ) << endl;
    cout << _tcslen(s)    << endl;
}

// 4. WBCS( 2바이트로 인식 )
int main()
{
    wchar_t s[] = L"ABCD가나다라";

    cout << sizeof(s) << endl;    // 18 (null 문자도 2byte )

    cout << strlen((char*)s) << endl;

    cout << wcslen(s) << endl;
}
// 5. DBCS
int main()
{
    char s[] = "ABCD가나다라";

    cout << sizeof(s) << endl;    // ?

    char* p = s;

    while(*p)
    {
        cout << p << endl;

        // p = p + 1;    // 단순 포인터 연산을 사용한 경우

        p = CharNext(p);    // DBCS 관련함수를 통해서 다음 글자 얻기
    }
    return 0;
}
Tag | ,

9.13(목) 실습-2

from Study/API 2007/10/10 11:31 view 18979
// 1. 각종 FindWindow 활용
int
main()
{
    HWND h = FindWindow( 0, "계산기" );    // 열려 있는 메뉴의 핸들을 얻는다.

    PostMessage( h, WM_QUIT, 0, 0 );

    //DestroyWindow( h ); // 안된다.이유는 이론편에..
}

int main()
{
    while( 1 )
    {
        Sleep(3000);

        HWND h = FindWindow( "#32768", 0 );    // 열려 있는 메뉴의 핸들을 얻는다.
      ShowWindow( h, SW_HIDE );
    }
}

int main()
{
    //HWND hwnd = FindWindow(
    //    0,            // 윈도우 클래스 이름
    //    "계산기" );    // 캡션바 내용

    // progman 은 바탕화면 이다.
    HWND hwnd = FindWindow( "Shell_TrayWnd", 0 ); // taskbar의 핸들을 얻음.
       
    if ( hwnd == 0 )
    {
        cout << "계산기를 먼저 실행하세요." << endl;
        return 0;
    }
    // -----------------------------
    HRGN h = CreateEllipticRgn( 0, 0, 300, 300 );
    SetWindowRgn( hwnd, h, TRUE );

    //SetMenu( hwnd, 0 );

    //if( IsWindowVisible( hwnd ) )
    //    ShowWindow( hwnd, SW_HIDE );
    //else
    //    ShowWindow( hwnd, SW_SHOW );
}

// 2. DLL 만들어보기


// Dll 소스
 //a.c

#include <stdio.h>    // 이 안에 wchar_t 가 typedef되어 있다.
#define DLLSOURCE
#include "a.h"    //    DLL 헤더

void PutStringA( const char* s )
{
    printf(s);
}
void PutStringW( const wchar_t* s )
{
    wprintf(s);
}
 //a.h

// DLL 내의 모든 함수의 선언을 제공한다.

// 이헤더는 DLL의 제작자가 사용할 때는 각 함수가 export 되도록 한다.
//  DLL 사용자가 사용할 때는 import  되도록 한다.

// 결국 MFC에서 등장하는 AFX_EXT_CLASS의 개념도  아래 DLLAPI의 개념과 완전 동일하다.

 

#ifdef DLLSOURCE

#define DLLAPI __declspec(dllexport)

#else

#define DLLAPI __declspec(dllimport)

#endif

 

#ifdef __cplusplus

extern "C"{

#endif

                  DLLAPI void PutStringA( const char* s );

                  DLLAPI void PutStringW( const wchar_t* s );

#ifdef __cplusplus

}

#endif

 

// UNICODE 매크로에따라서함수를결정할수있는매크로를제공한다.

#ifdef UNICODE

#define PutString    PutStringW

 

#else

#define PutString    PutStringA

#endif

// 1. C/C++ 을모두지원하기위해__cplusplus 사용

// 2. export/import 를위한C++ 지시어를알아야한다.

////////////////////////////////////////////////////////////////////////////////
// DLL을 사용하는 방법

#include "a.h"                                // 1. 헤더 include
#pragma comment(lib, "MyDll.lib")    // 2. lib를 링커에게 알려준다.

int main()
{
    PutStringA("hello");
    PutStringW(L"World\n");
}


Tag | ,

9.13(목) 실습-1

from Study/API 2007/10/10 11:18 view 22616
// 1. 가상주소값 알아보기
int
x = 0;

int main()
{
    cout << main << endl;
    cout << &x << endl;

    // Exe의 가상주소를 구한다.( 이값이 instance )
    void* p1 = GetModuleHandle(0);
    void* p2 = GetModuleHandle("ntdll.dll");
    void* p3 = GetModuleHandle("kernel32.dll");
    void* p4 = GetModuleHandle("user32.dll");
    void* p5 = GetModuleHandle("gdi32.dll");

    cout << "exe 주소        : " << p1 << endl;
    cout << "ntdll.dll 주소        : " << p2 << endl;
    cout << "kernel32.dll 주소    : " << p3 << endl;
    cout << "user32 주소        : " << p4 << endl;
    cout << "gdi32 주소        : " << p5 << endl;

    // 가상주소를 알때 모듈이름을 구하는 함수
    char name[256];
    GetModuleFileName((HMODULE)0x00400000, name, 256);

    cout << name << endl;
   
    // 이 함수는 User32.dll 에 있다.
    // 또한 내부적으로 Gdi32.dll의 함수를 사용한다.
    MessageBox( 0, "","",MB_OK);
   
    return 0;
}

// 2. DLL의 명시적 연결 : 헤더파일과 .lib 파일이 필요 없다. 단지 DLL만 있으면 된다.
//                        단, DLL이 가진 함수의 모양(signaure)는 알아야 한다.
typedef void (*F)(const char* s);

int main()
{
    getch();

    HMODULE hDll = LoadLibrary( "MyDll.dll" );

    if( hDll == 0 )
    {
        printf("DLL을 찾을 수 없습니다.\n");
        return -1;
    }
   
    printf("DLL이 Load된 주소 : %p\n", hDll );
    //------------------------------------------
    // DLL 에서 함수 찾기
    F f = (F)GetProcAddress( hDll, "PutStringA" );

    if( f == 0 )
        printf("PutString 함수가 없습니다.\n");
    else
        f("AAA");

    getch();
    FreeLibrary( hDll );

    return 0;
}

// 3. 여러가지 이야기
// 링커에게 exe의 종류를 알려준다.
#pragma comment( linker, "/subststem:console" )

// 함수 호출 규약
// __cdecl : 모든 CPU가 지원하는 기계어 코드 생성
// __stdcall : 메모리 사용량이 __cdecl 보다 적다
// __fastcall : 가장 빠르게 동작하는 기계어 생성

// this : C++ 멤버 함수가 호출되는 원리 - this가 ecx로 전달
// naked : 디바이스 드라이버 만들 때 주로 사용 - stack Frame이 생략된다.

// 4. 윈도우 열거(EnumWindows)
BOOL
CALLBACK foo( HWND hwnd,  LPARAM lParam );
int main()
{
   
// 모든 Top-Level 윈도우를 열거한다.
    EnumWindows(
        foo,   
// Callback 함수
        0 );    // 함수의 2번째 인자로 보낼 Data
}

BOOL CALLBACK foo( HWND hwnd,  LPARAM lParam )
{
   
char cname[256];
   
char title[256];

   
if ( IsWindowVisible( hwnd ) == FALSE ) return TRUE; // 안보이는 윈도우.
    if ( GetWindowTextLength( hwnd ) == FALSE ) return TRUE; // 캡션 글자가 없는경우

    // 작업관리자는 바탕화면을 열거 하지 않는다.
    // 작업관리자 자신도 열거 하지 않는다.

    // 소유된 윈도우도 열거 하지 않는다.(OWNER)
    // Getparent() : 부모 또는 소유 윈도우의 핸들을 구한다.
    if ( GetParent(hwnd) != 0 ) return TRUE;    // 소유된 윈도우 제거

    if ( IsWindowVisible( hwnd ) == FALSE ) return TRUE; // 안보이는 윈도우.

    GetClassName( hwnd, cname, 256 );
    GetWindowText( hwnd, title, 256 );

    cout << hex << hwnd <<
"-" << cname << "-" << title << endl;

   
return TRUE;    // 계속 찾으라는 의미
                    // 여기서 FALSE를 리턴하면 더이상 열거하지 않는다.
}

// 5. lib를 만들어 보기.
// a.h
// 라이브러리 파일에 있는 모든 함수의 선언을 제공해 준다.
// C++ 에서 사용할 경우를 대비 해야 한다.
#ifdef __cplusplus
extern "C" {
#endif

int Add(int , int);

#ifdef __cplusplus
}
#endif
// a.c
int Add( int a, int b )
{
   
return a + b;
}
// 빌드하면 DLib.lib 가 만들어진다.

// 6. 정적 라이브러라 사용하기.
// 정적 라이브러리를 사용하는 방법
// 1. 헤더 include
#include "aa.h"   
// 2. lib를 링커에게 알려준다.
#pragma comment(lib, "DLib.lib")

int CppAdd( int a, int b )
{
   
return a + b;
}
int CppAdd( int a, int b, int c )
{
   
return a + b + c;
}

int main()
{
   
int n = Add(1, 2);
    printf(
"%d\n", n);
    n = CppAdd(1, 2);
    printf(
"%d\n", n);
    n = CppAdd(1, 2, 3);
    printf(
"%d\n", n);
}



Tag | ,