'API & MFC/API & 시스템프로그래밍'에 해당되는 글 24건

  1. 2010.02.13 메시지 기본원리
  2. 2010.02.10 프로세스
  3. 2010.02.09 ATOM
  4. 2010.02.03 간단한 DLL 예제 (1)
  5. 2010.02.03 리스트뷰
  6. 2010.02.02 WM_USER And WM_APP
  7. 2010.02.02 레지스트리
  8. 2010.01.28 o/s의 role
  9. 2010.01.25 파일매핑예제
  10. 2010.01.25 WNDCLASS 구조체

 

RESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam);


첫번째 인수(HWND hWnd) : 메시지를 받을 윈도우 핸들. 클래스로부터 여러 개의 윈도우가 만들어

졌을 때 어떤 윈도우로 전달된 메시지 인지를 구분해야 하므로 이 인수가 필요함.

두번째 인수(UINT iMessage) : Message ID이며 0x00 ~ 0x3FF 사이의 값이다. “WM_”으로 시작하는 상수로 정의 되어 있다.(전달된 메시지의 값)

WPARAM wParam, LPARAM lParam : 32비트 정수값이며 메시지의 추가 정보를 가진다.


메시지 큐


 

 

메시지는 시스템이나 사용자에 의해 발생한다.

키보드나 마우스 등의 사용자 입력 시 시스템은 이 입력에 대해 메시지를 발생시키며 또한

시스템 상황 변화를 통지하기 위해서도 메시지를 발생시킨다. 응용 프로그램도 윈도우간의

통신을 위해 메시지를 발생하며 특정 함수 호출에 의해 간접적으로 메시지가 발생하기도 한다.

윈도우즈라는 운영체제는 끊임없는 메시지의 생성과 처리를 무수히 반복하면서 실행되는

것 이므로 메시지는 윈도우즈 운영체제에서 중요하다고 할 수 있다.

메시지는 크게 메시지큐로 들어가는 (Queued)메시지와 큐에 들어가지 않고 곧바로

윈도우 프로시저로 보내지는 비큐(Non Queued)메시지로 구분된다.



 

윈도우 프로시져(Window Procedure) : 메시지를 처리하는 함수

 

- 윈도우 클래스당 하나씩 배정되며 메시지에 대응하는 방식을 정의하여 윈도우의 행동 양식을

   결정한다.

- 윈도우 클래스로부터 생성된 모든 윈도우의 메시지는 이 함수가 처리한다.

- 이름은 사용자가 마음대로 바꿀 수 있으나 일반적으로 WndProc이라는 이름을 사용한다.

- 4개의 인수를 가지며 정수값 하나를 리턴한다. 대부분 잘 처리했으면 0을 리턴하지만 어떤

   메시지는 처리 결과를 운영체제로 리턴하여 보고하는 경우도 있다.

Ex) WM_CREATE 는 초기화 과정에서 에러가 없으면 0을 리턴 에러가 발생했으면 -1을 리턴한다.

      WM_NCHITTEST  는 마우스가 윈도우의 어떤 부분에 있는지를 리턴한다.

  *WM_NCHITTEST : 윈도우에게 커서가 움직이거나 마우스버튼이 눌리거나 띄어졌을 때 메시지를 보낸다.



 




v  Window Procedure

모든 윈도우는 메시지를 처리하기 위해 메시지 처리 함수가 있어야 한다. 메시지 처리 함수의 모양은 아래 같다.

LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);

윈도우 클래스를 만들때 메시지 처리함수의 주소를 등록한다.

v   Non-Queued Message

사용자가 윈도우를 만들기 위해 CreateWindowEx()함수를 호출하면 윈도우가 만들어 지고 윈도우가 만들어 졌다는 사실을 사용자에게 알리기 위해 WM_CREATE라는 메시지가 메시지 처리함수에 전달된다.(메시지 처리 함수가 호출된다.)

이때 WM_CREATE 메시지는 Message Queue 놓이지 않고 직접 Window Procedure 전달 되는 이를 non-Queued Message라고 한다.

입력 메시지(마우스 메세지, 키보드 메시지) 제외한 대부분의 메시지가 non-Queued Message 이다.

 

LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {

switch( msg )     {

case WM_CREATE:

                           MessageBox( 0, "WM_CREATE도착", "", MB_OK);

                           return 0;

  

}

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE , LPSTR lpCmdLine, int nShowCmd)

{

HWND hwnd = CreateWindowEx(…);

ShowWindow(hwnd, nShowCmd);






v  Queue Message

마우스나 키보드 메세지들은 직접 Window Procedure 전달되지 않고 메시지 Queue 놓이게 되는데 이를 Queue Message라고 한다. Queue 놓인 메시지를 처리하려면 반드시 사용자가 Queue 놓여 있는 메시지를 가져오는 메시지 루프가 필요하다.

MSG msg;

while ( GetMessage( &msg, 0, 0, 0 ) )  {

       TranslateMessage(&msg);

       DispatchMessage(&msg);

}

GetMessage() 메시지 Q WM_QUIT 메시지가 있을 경우에만 FALSE 리턴한다. 그래서 코드는 WM_QUIT메세지가 Q 들어 올때 까지는 무한 루프가 된다.

v   프로그램의 종료

사용자가 만든 윈도우가 파괴될 나오는 메시지는 WM_DESTROY 이다. 그러므로 사용자가 윈도우를 파괴 해도 프로그램은 계속 메시지 루프를 돌게 된다.( 하지만 윈도우는 파괴 되었다.- 모니터 화면에는 이상 아무 것도 없다.)

윈도우를 1 만든 경우 프로그램의 main 윈도우가 파괴 프로그램을 같이 종료 되게 하려면 WM_DESTROY 메시지에서 WM_QUIT메세지를 메시지 Q 넣는 작업을 해야 한다.

case WM_DESTROY:

       PostQuitMessage( 0 );             return 0;

v   처리하지 않은 메시지

메시지 처리 함수에서 발생된 메시지를 처리하지 않은 경우 반드시 아래 함수로 보내서 default 처리가 되게 해야 한다.

LRESULT CALLBACK DefWindowProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);









메시지 루프

 

- 사용자에 의해 입력된 메시지는 시스템 메시지 큐에 일단 저장되고 스레드 메시지 큐로 이동했다가 메시지 루프에 의해 해당 윈도우의 윈도우 프로시저로 보내져 처리된다.

 - 메시지는 최종 처리되기 직전까지 계속 큐에 유지되는데 이때 메시지는 다음과 같이 정의된 구조체의 형태로 존재한다.


Typedef struct tagMSG{HWND hwnd; UINT message; PARAM wParam; LPARAM lParam; WORD time; POINT pt;}MSG;


HWND
hWnd : 메시지를 받을 윈도우 핸들.

UINT iMessage : 전달된 메시지의 값

WPARAM wParam, LPARAM lParam : 메시지의 추가 정보를 가진다.

 

DWORD time : 메시지가 발생한 시간(time)

POINT pt : 발생시의 마우스 좌표(pt)

시간과 마우스 좌표는 모든 메시지들이 필요로 하는 정보가 아니므로 WndProc까지 전달되지 않는다.
필요할 경우 다음 두 함수를 사용하여 직접 조사해야 한다.

      ※ DWORD GetMessagePos(VOID) : 하위워드(LOWORD)x좌표, 상위워드(HIWORD)y좌표를 리턴한다.

      ※ LONG GetMessageTime(VOID) : 메시지 발생 시간을 부팅된 후 경과된 1/1000 단위로 리턴한다.


 

 - 메시지 루프는 메시지 큐에서 메시지를 꺼내 메시지 처리 함수로 보내는 일을 한다.

 - 보통 WinMain의 제일 끝부분에 위치하며 다음과 같이 그 형태가 정형화 되어 있다.


while(GetMessage(&Message,NULL,0,0)

{

     TranslateMessage(&Message);

     DispatchMessage(&Message);

}


- while문에 싸여져 있는데 이 루프는 프로그램이 끝날 때까지 계속반복된다.

    (메시지큐에 WM_QUIT[kwɪt]이라는 윈도우 메시지가 도착해 있으면 위의 반복문 조건속에 있는

     GetMessage함수는 FALSE값을 리턴하고 종료한다.)

      * WM_QUIT : PostQuitMessage 함수가 실행되면 발생하는 메시지

 

BOOL GetMessage(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax);

 

 - 스레드 메시지 큐에 대기중인 메시지를 꺼내 첫 번째 인수로 전달된 MSG 구조체에 복사한다.

 - 복사한 메시지를 큐에서 제거하고 TRUE리턴하며, 만약 큐에서 가져온 메시지가 WM_QUIT이면

    FALSE 리턴하여 메시지 루프를 탈출할 수 있다.

 

LPMSG lpMsg : MSG 구조체의 번지를 지정한다.

HWND hWnd : 현재 메시지를 큐에 올린 윈도우의 핸들값. 메시지를 처리해서 되돌려 줄때 필요하다.

UINT wMsgFilterMin : 회수된 메시지의 범위 중 최소값을 정수형태로 지정

UINT wMsgFilterMax : 회수된 메시지의 범위 중 최대값을 정수형태로 지정

 

*wMsgFilterMin : 첫번째 키보드 메시지인 WM_KEYFIRST 메시지 혹은 첫번째 마우스 메시지를 저장하는 WM_MOUSEFIRST 메시지 정수값을 저장한다.

*wMsgFilterMax : 마지막 키보드 메시지인 WM_KEYLAST 메시지 혹은 마지막 마우스 메시지를 저장하는 WM_MOUSELAST 메시지 정수값을 저장한다.

*wMsgFilterMin, wMsgFilterMax에 메시지의 범위를 지정하면 이 범위 내의 메시지만 가져온다.

*wMsgFilterMinwMsgFilterMax 인자의 값이 둘 다 0이면  GetMessage함수는 메시지 사용범위의  지정없이  모든 메시지를 돌려준다.

 

TranslateMessage


 
GetMessage 함수에 의해 큐로부터 가져온 메시지는 WM_QUIT가 아닌 한은 TranslateMessage 함수로 전달된다. 이 함수는 가상키 입력을 문자 입력(WM_CHAR)으로 바꾸는 역할을 하며 가상키 입력이 아닌 경우는 아무 처리도 하지 않는다.

* 컴퓨터의 가장 기본적인 입출력 장치는 아직까지는 키보드이다. 입력이 발생했을 경우 윈도우즈는 포커스를 가진 프로그램에게 키보드 메시지(WM_CHAR)를 보내주며 프로그램은 이 메시지를 받아 키보드 입력을 처리한다.(포커스(FOCUS)를 가진 프로그램이란 활성화되어 있는 윈도우를 말하며 한번에 오직 하나의 프로그램만 활성화 된다.멀티 태스킹 환경이라도 활성화될 수 있는 프로그램은 오직 하나밖에 없으며 활성화된 프로그램만 포커스를 가지고 키보드 입력을 받아들일 수 있다.


 

 DispatchMessage


메시지를
윈도우 프로시저로 보내 처리하도록 하는데 MSG 구조체의 hwnd 멤버를 보고 정확하게 목적 윈도우의 메시지 처리 함수로 배달한다. 윈도우 핸들로 부터 어떤 윈도우 프로시저에게 메시지를 전달할 것인가를 결정하는 중요한 일을 이 함수가 담당한다.




출처 - 선문비트 최강사님 도큐먼트

'API & MFC > API & 시스템프로그래밍' 카테고리의 다른 글

메시지 기본원리  (0) 2010.02.13
프로세스  (0) 2010.02.10
ATOM  (0) 2010.02.09
간단한 DLL 예제  (1) 2010.02.03
리스트뷰  (0) 2010.02.03
WM_USER And WM_APP  (0) 2010.02.02
Posted by 아몰라
TAG API

댓글을 달아 주세요

정의  - 실행중인 프로그램 (파일이 실행되어 메모리에 적재되면 프로세스가 된다.)

내용 -  프로세스는 실행중인 프로그램이지만 작업의 주체는 아니다. 작업은 프로세스 내의 쓰레드가 담당한다.

프로세스는 각각 4GB의 주소 공간과 파일, 메모리, 스레드 등의 객체들을 소유하며 프로세스가 종료될 때 프로세스가 소유한 모든 자원은 운영체제의 의해 파괴된다. 모든 것은 프로세스의 의해 소유되며 스레드는 윈도우와 메시지 큐, 스택만 소유한다. 객체간의 소유 관계는 프로세스 > 스레드 > 윈도우 로 정리할 수  있다.



<프로세스 생성 함수> - WinExec, CreateProcess.

 

UINT WinExec (LPCSTR lpCmdLine, UINT uCmdShow)

한 프로그램에서 다른 프로그램을 실행하고자 할 때는 Win32 AP가 제공하는 프로세스 생성 함수를 사용한다. 프로세스를 생성하는 가장 간단한 함수는 WinExec이다

lpCmdLine

실행 시키고자 하는 프로그램의 이름, (완전 경로를 줄 수 있다.)

uCmdShow

실행 직 후 프로그램이 어떻게 보일지 지정.(기본 SW_SHOWNORMAL)

Ex)

UINT WinExec(“Notepad.exe”,SW_SHOWNORAML);

 

BOOL CreateProcess (LPCTSTR lpApplicationName, LPTSTR lpCmdLine,

LPSECURITY_ATTRIBUTES lpProcessAttributes,

LPSECURITY_ATTRIBUTES lpThreadAttributes,

BOOL bInheritHandles,  DWROD dwCreationFlags,

LPVOID lpEnvironment,  LPCTSTR lpCurrentDirectory,

LPSTARTUPINFO lpStartupInfo,

LPPROCESS_INFORMATION lpProcessInformation  );

프로세스를 생성하는 함수. 새로 만든 프로세스의 메인 윈도우가 어떻게 초기화될지 정하는 구조체인STARTUPINFO 구조체와 생성된 프로세스의 정보를 대입 받기 위한 구조체인 PROCESS_INFORMATION 구조체가 꼭 필요하다.[출처] [API] 프로세스|작성자 흡연토끼

à10개의 인수를 가지고 있는데 이 중 반드시 필요한 인수는 4가지 뿐이며 나머지는 NULL

줄 수 있다.

 

lpApplicationName

실행하고자 하는 프로세스 이름

lpCmdLine

명령행 인수를 지정한다.

bInheritHandles

상속 가능한 핸들에 대해 자식 프로세스에게 상속할지를 결정.(null)

lpStartupInfo

메인 윈도우의 초기화를 정하는 구조체.

lpProcessInformation

생성된 프로세스의 정보를 받기위한 구조체.

EX)

CreateProcess(NULL,”NotePad.exe”,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi);






프로세스가 자기 자신을 종료하는 가장 간단하고 일반 적인 방법은 WM_CLOSE메시지를 보내거나 DestoryWindow로 메인윈도우를 파괴하는것이다. 이때 WM_DESTORY에서 PostQuitMessage를 호출하여 메시지 루프를 종료한다.

 

 

<프로세스 종료 함수>

 

- void ExitProcess(UNIT uExitCode);

 함수가 호출되면 프로세스는 정리 작업이 들어가고 즉각 종료된다.

 

     프로세스와 연결된 모든 DLL을 종료시키기 위해 각 DLL DllMain함수가 호출되며

        dll들은 스스로 정리 작업을 한다.

     열려진 모든 핸들을 닫는다.

     실행중인 모든 스레드를 종료한다.

     프로세스 커널 객체와 스레드 객체는 신호상태가 되며 이 객체를 기다리는 다른 프로세스는 대기상태를 해제한다.

     프로세스의 종료코드는 STILL_ACTIVE에서 ExitProcess가 지정한 종료값이 된다.

 

-BOOL TerminateProcess(HANDLE hProcess,UINT uExitCode);

 프로세스 외부에서 다른 프로세스를 종료하는 메소드, ExitProcess에 비해 종료 대상이 되는 프로세스의 핸들을 가지므로 자기 자신이 아닌 다른 프로세스를 강제로 종료 시킬 수 있다.

 

à TerminateProcess ExitProcess함수보다 더 위험하다. 이는 함수가 호출될 때는 동일한 작업이 수행되나 TerminateProcess는 연결된 DLL에게 종료 사실을 통지하지 않는다. 때문에 TerminateProcess함수로 강제로 프로세스를 종료한다면 정보를 잃어버리게 될 수 있다.


<프로세스 핸들>

윈도우즈는 GDI, USER, KERNEL의 세 가지 주요 DLL로 구성되어 있다. 각 모듈은 여러 종류의 객체를 관리하며 관리의 편의를 위해 핸들을 사용한다. 객체는 시스템 리소스를 나타내는 일종의 데이터 구조체이며 이 구조체들은 보통 덩치가 크기 때문에 좀 더 간단한 32비트 정수값의 핸들로 관리된다. 각 모듈별 객체에는 어떤 것들이 있고 특징은 어떤지 정리해보자.

모듈

객체

특징

USER

윈도우, 커서, 캐럿, 아이콘

한 오브젝트에 하나의 핸들. 시스템 전역적

GDI

, 브러시, 비트맵, 팔레트

한 오브젝트에 하나의 핸들. 프로세스 지역적

KERNEL

파일, 프로세스, 스레드, 이벤트

보안 적용. 프로세스 한정적


USER 객체 - ProA에서 윈도우를 만들고 핸들을 받으면 그 핸들을 ProB에게 전달하면 ProB는 윈도우 핸들을 사용하여 ProA가 만든 윈도우를 마음대로 만질수 있다.

GDI객체 - ProA에서 펜을 만들고 hPen 핸들을 발급받아서 ProB로 보냈다고해서 ProB가 이 펜을 사용할 수 없다. GDI 객체는 언제든지 원하는대로 생성할 수 있는데다 공유할 필요가 없기 때문에 프로세스 지역적이다.

커널객체 - 윈도우즈는 멀티 유저를 지원하는데 파일이나 프로그램 모두 소유자를 지정할 수 있고 소유자만 액세스 하도록 권한을 설정할 수 있다. 그래서 커널 객체를 만드는 CreateProcess, CreateFile, CreateMutex 등의 함수들은 모두 보안 속성을 인수로 가진다.

이런 보안상의 이유로 커널 객체는 프로세스 한정적이다.
(프로세스 한정적 - 한 프로세스가 만든 핸들은 다른 프로세스에서 곧바로 사용할 수 없되 대신 다른 프로세스가 같은 객체를 다시 오픈 하여 또 다른 핸들을 사용할 수 있다는 뜻이다.)

ProA가 ProC를 생성해서 ProC의 핸들을 받는다. 그리고 ProB에게 ProC의 핸들을 보내준다. 하지만 ProB는 ProC를 열 수 있는 권한이 아직 있는지 없는지 확인이 안되었기 때문에 사용못한다. ProB가 ProC를 액세스하고 싶다면 다음 함수로 프로세스의 ID로부터 프로세스 핸들을 다시 열어야 한다. 

ID
- 프로세스간의 구분을 위한 중복되지 않는 식별값일 뿐이며 ID로부터 직접 프로세스를 제어할 수는 없다. ID로부터 핸들을 발급받아야만 비로소 이 객체를 제어할 수 있다.

<프로세스의 핸들 얻는 함수>

 

HANDLE OpenProcess(DWORD dwDesiredAccess, BOOL blnheritHandle, DWORD dwProcessld)

dwDesiredAccess

Flag 접근

blnheritHandle

Flag 상속

dwProcessld

프로세스 identifier

 

<자기자신의 프로세스 핸들 얻는 함수>

HANDLE GetCurrentProcess (VOID);  : 필요한 인자는 없으며 자기자신의 프로세스 핸들 값을 반환한다.




<
프로세스 종료 상태를 구하는 함수>
                  
BOOL GetExitCodeProcess (HANDLE hProcess, LPWORD lpExitCode);

프로세스의 종료 상태를 구하는 인수로 프로세스의 핸들을 주면 이 프로세스의 종료 상태를 lpExitCode에 리턴 해준다.

hProcess

프로세스의 핸들

lpExitCode

DWORD의 포인터형. 프로세스의 상태코드가 넘어온다.        성공 1, 실패 0반환.

 

<사용 예>

static DWORD ProcID = 0;

static HANDLE hProc = 0;

 

switch (iMessage) {

           case WM_USER:

                     ProcID = wParam;

                     hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcID);

                     return 0;

           case WM_LBUTTONDOWN:

                     GetExitCodeProcess(hProc, &ExitCode);

           }



.[출처] [API] 프로세스|작성자 흡연토끼

'API & MFC > API & 시스템프로그래밍' 카테고리의 다른 글

메시지 기본원리  (0) 2010.02.13
프로세스  (0) 2010.02.10
ATOM  (0) 2010.02.09
간단한 DLL 예제  (1) 2010.02.03
리스트뷰  (0) 2010.02.03
WM_USER And WM_APP  (0) 2010.02.02
Posted by 아몰라

댓글을 달아 주세요

아톰에 대해서 알기전에 아톰테이블에 대해서 먼저 알아보자.

아톰 테이블이란?

- 시스템이 유지하는 문자열 테이블
- 아톰들을 저장하는 해쉬테이블

아톰테이블에 문자열을 보관하면 저장된 문자열을 대표하는 정수값을 돌려준다. 그 값이 아톰이다.


 아톰 테이블의 종류


로컬 아톰테이블

- 지역아톰테이블에 저장
- 테이블을 만든 응용 프로그램 내에세만 사용가능
- 함수명 AddAtom, GetAtomName 등등


글로벌 아톰테이블

- 전역아톰테이블에 저장
- 시스템의 모든 응용 프로그램이 같이 사용
- 함수명 GlobalAddAtom, GloabalGetAtomName 등등

아톰함수정리

ATOM GlobalAddAtom(LPCTSTR lpString)
 <문자열 추가>
첫 번째 인자: 추가 하고자 하는 문자열
반환 값 : 아톰테이블에 추가된 문자열의 아톰을 준다.


ATOM GlobalDeleteAtom(ATOM nAtom) <문자열삭제>
첫 번째 인자: 삭제 하고자 하는 아톰
반환 값:  성공시 0 , 실패시 nAtom



UINT GlobalGetAtomName(ATOM nAtom, LPTSTR lpBuffer, int nSize)
 <아톰값으로부터 문자열 추출>
첫번재 인자: 헤당 아톰
두번째 인자: 아톰에서 찾은 문자열을 담을 버퍼공간

세 번째 인자:
버퍼공간 사이즈
반환 값:  실패 시 0


ATOM GlobalFindAtom(LPCTSTR lpString)
<문자열로부터 아톰값을 구한다.>
 

첫 번째 인자: 해당 문자열
반환 값 : 실패 시 0



아톰의 사용용도

- 문자열을 '키'로 가지는 자료들을 관리 할 때
     중복문자열을 저장하지 않는다.(Add함수로 같은 문자열을 저장하면 참조카운트가 늘어난다 1,2,3....Delete 함수로 참조인수가 0이 될 때 시스템은 아톰테이블에서 문자열삭제한다.)


- 문자열을 통한 해쉬함수가 필요한 경우








'API & MFC > API & 시스템프로그래밍' 카테고리의 다른 글

메시지 기본원리  (0) 2010.02.13
프로세스  (0) 2010.02.10
ATOM  (0) 2010.02.09
간단한 DLL 예제  (1) 2010.02.03
리스트뷰  (0) 2010.02.03
WM_USER And WM_APP  (0) 2010.02.02
Posted by 아몰라

댓글을 달아 주세요

 


사칙연산 예제

Dll 헤더파일

#ifndef __CAL_H
#define __CAL_H

#include <windows.h>

#ifdef DLLEXPORT
#define DLLTYPE __declspec(dllexport)
#define DLLTYPE2 extern "C" __declspec(dllexport)
#else
#define DLLTYPE __declspec(dllimport)
#define DLLTYPE2 extern "C" __declspec(dllimport)
#endif

class DLLTYPE Cal
{
 public:
 int Calplus(int Num1, int Num2);
 int Cal::CalMinus(int Num1, int Num2);
 int Cal::CalMul(int Num1, int Num2);
 int Cal::CalDiv(int Num1, int Num2);
 
};
#endif __CAL_H





DLL CPP파일

#define DLLEXPORT
#include "Cal.h"

int Cal::Calplus(int Num1, int Num2)
{
 return (Num1 + Num2);
}

int Cal::CalMinus(int Num1, int Num2)
{
 return (Num1 - Num2);
}

int Cal::CalMul(int Num1, int Num2)
{
 return (Num1 * Num2);
}

int Cal::CalDiv(int Num1, int Num2)
{
 return (Num1 / Num2);
}


#define DLLEXPORT을 선언하였다. 헤더파일에도 정의되어있기때문에 조건문에서 export로 되어서 수출하게된다.


사용파일

#pragma comment(lib, "Dll연습")
#include "Cal.h"
#include <stdio.h>
void main()
{
 Cal cal;
 
 cal.Calplus(2,4);
 
 printf("result = %d\n", cal.Calplus(2,4));
 printf("result = %d\n", cal.CalMinus(2,4));
 printf("result = %d\n", cal.CalMul(2,4));
 printf("result = %d\n", cal.CalDiv(2,4));

}



여기서는 Cal.h 를 인클루드만해서 쓰게 됨으로 DLLEXPORT가 중복이 안되서 조건문에서 import로 빠지게된다.
즉, 사용하겠다는 뜻이다.

'API & MFC > API & 시스템프로그래밍' 카테고리의 다른 글

프로세스  (0) 2010.02.10
ATOM  (0) 2010.02.09
간단한 DLL 예제  (1) 2010.02.03
리스트뷰  (0) 2010.02.03
WM_USER And WM_APP  (0) 2010.02.02
레지스트리  (0) 2010.02.02
Posted by 아몰라

댓글을 달아 주세요

  1. 2013.05.02 14:56

    젊을 때에 배움을 소홀히 하는 자는 과거를 상실하고 미래도 없다Topics related articles:


    http://npboy.tistory.com/4 新建文章 9

    http://yojo23.tistory.com/21 新建文章 12

    http://insajin.tistory.com/archive/20130208 新建文章 2

    http://zaehwan.tistory.com/69 新建文章 10

리스트뷰 -  ListBox가 발전된 형태로  좀 더 깔끔하고 다양한 기능을 사용할 수 있다.




리스트뷰 함수정리

ListView_GetItemCount()  :  등록된 항목의 개수

ListView_InsertItem()  :  새 항목 등록

ListView_SetItem()  :  항목의 정보를 변경(이미지 등)

ListView_SetItemText()  :  항목의 문자열을 변경

ListView_DeleteItem()  :  지정한 항목을 삭제

ListView_DeleteAllItems()  :  전체 항목을 삭제

ListView_GetItemText()  :  지정한 항목의 문자열을 얻어옴

ListView_GetNextItem()  :  옵션에 해당하는 항목의 인덱스 반환

ListView_FindItem()  :  제시한 조건과 일치하는 항목의 인덱스 반환

ListView_SetItemState()  :  지정한 항목의 상태 변경(포커스 등)





LVCOLUMN 구조체  -  LVCOLUMN 구조체에 헤더의 정보를 채운 뒤 LVM_INSERTCOLUMN 메시지 전송

Typedef struct_LVCOLUMN{
UINT mask;  :사용될 멤버 값 설정
int fmt;  :문자열의 정렬방법과 이미지 사용여부
int cx;  :헤더의 폭
LPTSTR pszText;  :보여질 문자열
int cchTextMax;  :문자열의 크기
int iSubItem;  :연결될 항목
#if(_WIN32_IE>=0x0300)  :IE의 버전(구 버전 이미지 사용불가)
int iImage;  :보여질 이미지
int iOrder;  :헤더의 순서
#endif
}LVCOLUMN,FAR*LPLVCOLUMN;



LVITEM 구조체 -  LVITEM 구조체에 항 정보를 채운 뒤 LVM_INSERTITEM  메시지 전송

Typedef struct_LVITEM{
UINT mask;  :사용될 멤버 값 설정
int iItem;  :항목의 Index설정
int iSubItem;  :항목의 Colum Index설정
UINT state;  :항목의 상태(focus, 선택 등)
UINT stateMask;  :상태를 설정
LPTSTR pszText;  :문자열(실제 내용)
int cchTextMax;  :문자열 길이
int iImage;  :왼쪽에 보여질 이미지의 인덱스
LPARAM lParam;  :항목의 추가 저장공간
#if(_WIN32_IE>=0x0300)  : IE의 버전(구 버전 들여쓰기 사용불가)
int iIndent;  :들여쓰기
#endif
}LVCOLUMN,FAR*LPLVCOLUMN;


 
LVFINDINFO 구조체 - LVFINDINFO 구조체에 검색할 정보를 채운 뒤 LVM_FINDITEM 메시지 전송

typedef struct tagLVFINDINFOW {
UINT flags;  :
검색 형태를 지정하는 옵션
LPCWSTR psz;  :검색할 문자열
LPARAM lParam;  :검색할 32bit Data
POINT pt;  :검색할 좌표값
UINT vkDirection;  :검색할 방향
} LVFINDINFOW, FAR* LPFINDINFOW;




#include <windows.h>
#include <commctrl.h>
#define IDC_LISTVIEW 150
#define LVIF_TEXT 151


LVCOLUMN COL; //열 구조체
LVITEM LI;          //항목 구조체
HWND hList;


void OnInitCOL(HWND hWnd)
{
 hList = CreateWindow(WC_LISTVIEW,NULL, WS_CHILD | WS_VISIBLE | WS_BORDER | LVS_REPORT, 150,18,240,60,hWnd,(HMENU)IDC_LISTVIEW,0,0);
 ListView_SetExtendedListViewStyle(hList,LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES);
//리스트뷰 스타일 초기화

 COL.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
 COL.fmt = LVCFMT_LEFT;
 
 COL.cx=80;
 COL.pszText="가";   
 COL.iSubItem=0;
 ListView_InsertColumn(hList,0,&COL);   

//첫번째 : 해당 리스트 핸들
//두번째 : 몇번째 열인지
//세번째 : 해당 열의 초기화상태
 
 COL.cx=80;
 COL.pszText="나";   
 COL.iSubItem=1;
 ListView_InsertColumn(hList,1,&COL);
 
 COL.cx=80;
 COL.pszText="다";  
 COL.iSubItem=2;
 ListView_InsertColumn(hList,2,&COL);
}


void OnInitITEM()
{
 LI.mask = LVIF_TEXT;
 LI.iItem = 1;         //행 (전체 화면 - 캡션포함)
 LI.iSubItem = 0;    //열
 LI.pszText = "1";  //문자열 값
 ListView_InsertItem(hList, &LI);
//초기화된 항목구조체 정보를 토대로 해당리스트에 삽입 

 ListView_SetItemText(hList, 0, 1, "2"); 
//첫번째: 해당 리스트 핸들
//두번째 : 행 (캡션 미 포함)
//세번째 : 열
//네번째 : 값
 ListView_SetItemText(hList, 0, 2, "3");
 
  
 LI.iItem = 2;
 LI.pszText = "4";
 ListView_InsertItem(hList, &LI);

 ListView_SetItemText(hList, 1, 1, "5");
 ListView_SetItemText(hList, 1, 2, "6");
 
 LI.iItem = 3;
 LI.pszText = "7";
 ListView_InsertItem(hList, &LI);

 ListView_SetItemText(hList, 2, 1, "8");
 ListView_SetItemText(hList, 2, 2, "9");
}



결과



'API & MFC > API & 시스템프로그래밍' 카테고리의 다른 글

ATOM  (0) 2010.02.09
간단한 DLL 예제  (1) 2010.02.03
리스트뷰  (0) 2010.02.03
WM_USER And WM_APP  (0) 2010.02.02
레지스트리  (0) 2010.02.02
o/s의 role  (0) 2010.01.28
Posted by 아몰라
TAG API, listview

댓글을 달아 주세요

윈도우 시스템은, 메시지구동 시스템으로 모든 이벤트는 메세지의 발생에 의해서 처리된다.


#define MY_USER 1000 
이렇게 선언할 경우 이미 1000이라는 값은 시스템이 내부적으로 예약해서 사용하는 상수일 수 있다.
그래서 이러한 현상을 막는 방법으로 WM_USER와 같은 사용자가 정의 할 수 있는 상수공간을 마련해두었다.


설명 - 이 메시지는 실제로 정의되어 있는 시스템 메시지가 아니며 사용자 정의 메시지의 시작 범위를 지정하는 상수값이다. 메시지는 정수값 하나로 표현되는데 윈도우즈는 메시지의 범위를 다음과 같이 정의하고 있다.



<범위 설명>

0~WM_USER-1
운영체제가 정의하는 시스템 메시지. WM_PAINT, WM_TIMER 등의 메시지들이 모두 이 범위에 속한다.

WM_USER~WM_APP-1
윈도우 클래스가 정의하는 사용자 정의 메시지
WM_APP~0xBFFF
응용 프로그램이 정의하는 사용자 정의 메시지

0xC000~0XFFFF
문자열로 등록되는 메시지

0x10000~ 이후의 사용을 위해 예약된 영역이며 현재는 사용되지 않는다.


WM_USER

WM_USER는 한 윈도우 클래스를 위한 고유의 메시지를 정의하기 위한 상수값이며 이 범위 이후부터 윈도우 클래스의 사용자 정의 메시지를 만들 수 있다. 이 값은 0x400으로 정의되어 있으며 보통 WM_USER+n으로 사용자 정의 메시지를 정의한다. 이때 n은 1보다 큰 정수이며 사용자 정의 메시지간의 구분을 위해 사용된다. 여러 개의 사용자 정의 메시지가 필요하다면 WM_USER+1, WM_USER+2, WM_USER+3,... 식으로 계속 n을 증가시켜 가며 메시지를 정의할 수 있다. 윈도우즈는 WM_USER이후 0x8000까지 사용자 정의 메시지 영역으로 정의하고 있으므로 n은 최대 0x7c00까지 가능하다. WM_USER+n을 곧바로 사용할 수도 있으며 자주 사용할 경우 다음과 같이 매크로를 정의하여 별도의 메시지를 만들 수 있다.

#define WM_MYMESSAGE WM_USER+1

이렇게 매크로를 정의해 놓고 이후부터 WM_MYMESSAGE라는 명칭을 대신 사용하면 된다.

주의
- 표준 컨트롤 중 일부는 자신만의 사용자 정의 메시지를 정의하여 사용하고 있다. 따라서 WM_USER+n은 가급적이면 한 윈도우 클래스내에서만 정의하여 사용해야 하며 응용 프로그램간의 통신에는 사용하지 않는 것이 바람직하다.
- 표준 컨트롤을 서브클래싱했을 경우 함부로 WM_USER+n을 사용하면 표준 컨트롤 고유의 메시지와 충돌이 발생할 수 있다.



예제
 
다음 예제는 사용자 정의 메시지로 윈도우를 이동시킨다.

LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
        HDC hdc;
        PAINTSTRUCT ps;
        RECT wrt;
        TCHAR Mes[]="왼쪽 마우스 버튼을 누르면 이동합니다";

        switch(iMessage) {
        case WM_USER+1:
                GetWindowRect(hWnd,&wrt);
                wrt.left+=wParam;
                wrt.right+=wParam;
                wrt.top+=lParam;
                wrt.bottom+=lParam;
                MoveWindow(hWnd,wrt.left,wrt.top,wrt.right-wrt.left,wrt.bottom-wrt.top,TRUE);
                return 0;
        case WM_LBUTTONDOWN:
                SendMessage(hWnd,WM_USER+1,(WPARAM)-3,(LPARAM)5);
                return 0;
        case WM_PAINT:
                hdc=BeginPaint(hWnd, &ps);
                TextOut(hdc,10,10,Mes,lstrlen(Mes));
                EndPaint(hWnd, &ps);
                return 0;
        case WM_DESTROY:
                PostQuitMessage(0);
                return 0;
        }
        return(DefWindowProc(hWnd,iMessage,wParam,lParam));
}

이 예제에서 WM_USER+1은 윈도우를 이동하라는 뜻이며 wParam은 수평 이동 거리, lParam은 수직 이동 거리로 정의하였다. WM_USER+1을 받으면 이 인수들이 지정하는 거리만큼 윈도우를 이동시킨다.

WM_APP

#define WM_MYMESSAGE WM_APP+1

이렇게 매크로를 정의해 놓고 이후부터 WM_MYMESSAGE라는 명칭을 대신 사용하면 된다. WM_USER도 사용자 정의 메시지를 정의하는 용도로 사용되지만 표준 컨트롤중에 이미 WM_USER를 사용하는 컨트롤이 있으므로 중복될 위험성이 있다. 반면 WM_APP는 시스템이 전혀 이 영역을 사용하지 않고 있으므로 중복될 위험이 전혀 없으며 응용 프로그램간의 통신에 사용하기에 적합하다. 두 응용 프로그램의 약속에 의해 WM_APP+n 메시지를 정의하여 사용하면 된다.

WM_USER는 윈도우 클래스를 위한 사용자 정의 메시지이며 WM_APP는 응용 프로그램을 위한 사용자 정의 메시지라는 점이 다르다. 그러나 이 구분은 어디까지나 권장 사항일 뿐이지 강제 사항은 아니다. WM_USER를 응용 프로그램간의 통신에 사용하더라도 충돌이 없다는 확신만 있다면 가능하다. 다만 잠재적인 충돌 가능성이 있을 수 있다는 것을 고려할 때 바람직하지는 않다.

정리

이런 상황을 고려해 보자. MyApp에서 Con1이라는 커스텀 컨트롤을 사용하는데 이 컨트롤은 자신에게 변화가 있을 때 WM_USER+1이라는 통지 메시지를 부모 윈도우로 보내도록 되어 있다. 이런 상황에서 MyApp가 자신의 고유 용도로 WM_USER+1을 다시 정의한다면 메시지간의 충돌이 발생하게 된다. 이런 상황을 방지하기 위해 운영체제는 WM_USER를 내부적인 용도로 WM_APP를 응용 프로그램간의 통신에 사용하도록 권장하는 것이다. 하지만 WM_APP도 여전히 충돌이 발생할 가능성이 있으므로 좀 더 안전한 방법으로 메시지를 정의하고자 한다면 RegisterWindowMessage 함수로 문자열 메시지를 등록하여 사용하는 것이 좋다.


 

리턴값의 의미는 정해져 있다. 응용 프로그램이 의미를 정해서 사용할 수 있다. 이 메시지로 어떤 질문을 하고자할 때는 리턴값을 정의하며 그렇지 않을 경우는 통상 리턴값을 사용하지 않는다.



출처 http://www.winapi.co.kr/reference/Message/WM_USER.htm


'API & MFC > API & 시스템프로그래밍' 카테고리의 다른 글

간단한 DLL 예제  (1) 2010.02.03
리스트뷰  (0) 2010.02.03
WM_USER And WM_APP  (0) 2010.02.02
레지스트리  (0) 2010.02.02
o/s의 role  (0) 2010.01.28
파일매핑예제  (0) 2010.01.25
Posted by 아몰라

댓글을 달아 주세요

정보의 저장

¢  프로그램은 실행 중에 사용자가 입력한 옵션 설정이나 프로그램 스스로 만들어낸 정보들을 다음 실행을 위해 그 정보를 저장 해두어야 한다.

¢  이런 정보는 사용자의 정보가 아니라 프로그램 자신의 정보이다

¢  프로그램의 설정 정보를 저장하는 방법에는 INI파일을 쓰는 방법과 레지스트리를 쓰는 방법이 있다.



레지스트리의 특징

¢  윈도우의 환경설정에 대한 모든 정보가 저장되어 관리되고 있는 Windows의 핵심적인 데이터베이스이다.

¢  다중 환경설정을 저장할 수 있다.

¢  INI 파일과 달리 크기가 64KB를 초과할 수 있다.

¢  INI 파일에 비해 속도가 빠르다.

¢  백업 및 복구가 간단하다.

 

레지스트리의 구조

 

¢  레지스트리는 디렉토리 구조와 유사한 계층적 구조로 구성

¢  각각의 가지(레지스트리 편집기에서 폴더 아이콘으로 표시되는)는 키라고 부르며, 각각의 키는 하위키를  포함할 수 있으며, 각각의 키는 값을 포함할 수 있다.

¢  이 값에 레지스트리에 저장되는 실제 정보가 저장됨



함수정리

레지스트리 키 생성 함수

LONG RegCreateKeyEx(HKEY hKey, LPCTSTR lpSubKey, DWORD Reserved,                                   LPTSTR lpClass, DWORD dwOptions, REGSAM Desired, LPSECURITY_ATTRIBUTES lpSecurity, PHKEY hkResult, LPDWORD lpdwDisposition);


hKey :
새로 만들어지는 부모키 지정

     - HKEY_CLASSES_ROOT : 응용 프로그램을 위한 OLE정보와 모든 파일유형 정보 저장

     - HKEY_CURRENT_USER : 현재 로그인한 사용자를 위한 정보 저장

     - HKEY_LOCAL_MACHINE : 컴퓨터에 설치된 하드웨어와 소프트웨어에 대한 모든 정보 저장

     - HKEY_USERS : 컴퓨터를 사용하는 사용자 각각에 대한 속성을 저장

     - HKEY_CURRENT_CONFIG : 현재 하드웨어의 설정을 저장


lpSubKey : 만들고자 하는 서브키를 지정하는 널 종료 문자열로 반드시 지정해야 함.

                hKey 서브에 여기서 지정한 키가 생성됨.

Reserved : 예약된 인수, 0으로 지정

lpClass : 생성되는 키의 클래스를 지정하는 문자열

dwOptions : 생성하는 키의 옵션

   - REG_OPTION_NON_VOLATILE : 레지스트리에 저장되는 정보는 파일에

                                                  영구 저장되므로 재부팅해도 정보 유지

samDesired : 보안속성

   - KEY_ALL_ACCESS : 읽기, 쓰기 할 때 사용

   - KEY_WRITE : 쓰기,  KEY_READ : 읽기

lpSecurityAttribute : 생성된 키값이 상속될 것인가 지정하는 인수, NULL이면 상

                            속되지 않음


phkResult  : 만들어지거나 열려진 키값이 대입되는 변수 포인터

                  여기에 HKEY구조체 변수를 대입

lpdwDisposition : 키가 새로 생성되었는지 기존의 키가 오픈된 것인지 리턴받기

                         위한 출력용 변수


열려진 키에 값을 저장하는 함수

LONG RegSetValueEx(HKEY hKey, LPCTSTR lpValueName, DWORD Reserved,  DWORD dwType, CONST BYTE *lpData, DWORD cbData);


hKey :
값을 저장하고자 하는 키 핸들(현재 열려진 키)

lpValueName : 값의 이름

Reserved : 이 인수는 사용하지 않음

dwType : 값의 데이터 타입을 지정 (대부분의 정보를 저장할 수 있다)

    - REG_BINARY : 이진 데이터

    - REG_SZ : 문자열

lpData : 저장하고자 하는 데이터의 포인터

cbData : 데이터의 크기


저장한 위치의 값을 읽어오는 함수

LONG RegQueryValueEx(HKEY hKey, LPTSTR lpValueName, LPDWORD lpReserved,                          LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData);


hKey :
값을 저장하고자 하는 키 핸들(현재 열려진 키)

lpValueName : 값의 이름

lpReserved : 이 인수는 사용하지 않음

lpType : 읽은 값의 타입을 대입받을 변수의 포인터

lpcbData : 실제 복사된 데이터의 크기를 리턴, 대입받을 변수의 크기를 대입

RegCreateKeyEx(), RegSetValueEx(), RegQueryValueEx() 이 함수들은 제대로 읽거나 저장

                                                                   했다면 ERROR_SUCCESS(0)가 리턴 된다



열려진 레지스트리 키를 닫는 함수


 

LONG RegCloseKey(HKEY hKey);

레지스트리 키도 메모리를 소모하므로 사용하고 난 후에는 해제를 해야함



실습예제

#include <windows.h>
#include "resource.h"


BOOL CALLBACK DlgProc(HWND hDlg,UINT iMessage,WPARAM wParam,LPARAM lParam);

#define CURRENT HKEY_CURRENT_USER
#define KEY "SoftWare\\Bit\\Test\\"

 

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nShowcmd)
{
 DialogBox(hInstance,MAKEINTRESOURCE(IDD_DIALOG1),0,DlgProc);  

 return 0;
}

BOOL CALLBACK DlgProc(HWND hDlg,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
 TCHAR str[256];
 HKEY key;
 DWORD dwDisp;
 DWORD Size;  //불러올때 사이즈

 switch(iMessage)
 {
 case WM_INITDIALOG:  break;
 
 case WM_COMMAND:

  switch(LOWORD(wParam))
  {
  case IDOK: //저장하기
   
   GetDlgItemText(hDlg, IDC_EDIT1, str, 256);
   RegCreateKeyEx(CURRENT, KEY"Edit",0,NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, 0,&key, &dwDisp);
   RegSetValueEx(key, "STR", 0, REG_SZ, (LPBYTE)str, strlen(str)+1);
   RegCloseKey(key);
   break;

  case IDOK2: //불러오기

   RegCreateKeyEx(CURRENT, KEY"Edit",0,NULL, REG_OPTION_NON_VOLATILE,KEY_READ,0, &key, &dwDisp);
   RegQueryValueEx(key, "STR", 0, NULL, (LPBYTE)str, &Size);
   MessageBox(hDlg, str, "", MB_OK);
   RegCloseKey(key);
   break;
  case IDCANCEL:
   EndDialog(hDlg,IDCANCEL);
   break;
  }

  return TRUE;
 
 }
 return FALSE;
}

'API & MFC > API & 시스템프로그래밍' 카테고리의 다른 글

리스트뷰  (0) 2010.02.03
WM_USER And WM_APP  (0) 2010.02.02
레지스트리  (0) 2010.02.02
o/s의 role  (0) 2010.01.28
파일매핑예제  (0) 2010.01.25
WNDCLASS 구조체  (0) 2010.01.25
Posted by 아몰라
TAG registry

댓글을 달아 주세요

1. 스케줄러

2. MMU 메모리 매핑 유닛

3. Interrupt 관리  - 하드웨어 관리

App > Shell > O/S > Kernel

O/S(Kernel) - 컴퓨터 시스템의 핵이다.


4. NetWork

'API & MFC > API & 시스템프로그래밍' 카테고리의 다른 글

WM_USER And WM_APP  (0) 2010.02.02
레지스트리  (0) 2010.02.02
o/s의 role  (0) 2010.01.28
파일매핑예제  (0) 2010.01.25
WNDCLASS 구조체  (0) 2010.01.25
스레드의 함정  (0) 2010.01.25
Posted by 아몰라

댓글을 달아 주세요

- 파일 오픈                                                                  hF=CreateFile("test.txt")

- 파일 내용을 메모리에 올린다                                        hMapF=CreateFileMapping(hF)

- 메모리에 올려진 첫번째 주소를 얻는다.                          pF=MapViewOfFile(hMapF)

- 첫번째 주소로 메모리 내용을 조작한다.

- 중간중간에 변경된 내용을 강제로 디스크에 쓰게만든다.    FlushViewOfFile(pF)

- 해제.                                                                        UnmapViewOfFile(pF);

- 해제.                                                                        CloseHandle(hMapF);

- 파일 닫기.                                                                 CloseHandle(hF);

<예제>

#include <windows.h>
#include <stdio.h>

 

int main(int argc, char *argv[])
{
 HANDLE hF, hMapF;
 DWORD fSize, i;
 char *pF, *pFtmp;

 

 hF=CreateFile("test.txt",GENERIC_READ|GENERIC_WRITE, 0,
                                  NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

 

 fSize=GetFileSize(hF,NULL);

 

 hMapF=CreateFileMapping(
                                         hF,                          //file handle
                                         NULL,
                                         PAGE_READWRITE,
                                         0,                           //file size
                                         0,                           //file size
                                         NULL);                    //map name
 if(hMapF==NULL)
 {
  printf("CreateFileMapping() fail");
  CloseHandle(hF);
  return 1;
 }


 pF=MapViewOfFile(hMapF,FILE_MAP_ALL_ACCESS,0,0,0);
 
 pFtmp=pF;

 for(i=0;i<fSize;i++)
 {
  *pFtmp=(*pFtmp+1);
  pFtmp++;
 }

 

 //메모리 내용을 강제로 파일에 쓴다.
 FlushViewOfFile(pF, 0);

 

 UnmapViewOfFile(pF);

 CloseHandle(hMapF);

 CloseHandle(hF);


 return 0;
}





Share Memory를 만드는 프로세스:

CreateFileMapping->MapViewOfFile->UnmapViewOfFile->CloseHandle


Share Memory를 Open하는 프로세스:

OpenFileMapping->MapViewOfFile->UnmapViewOfFile->CloseHandle

 

<예제>

<공유메모리를 만들고 공유메모리에 데이터를 써넣는 프로그램>

#include <windows.h>
#include <stdio.h>

#pragma pack(1)

typedef struct tag_SMTEST
{
 char c;
 int  i;
 short s;
} SMTEST;


int main(int argc, char *argv[])
{
 HANDLE hMapF;
 SMTEST *psm;

 

// JJBSMTEST라는 이름으로 공유메모리를 만든다.

 hMapF=CreateFileMapping(
                                         INVALID_HANDLE_VALUE,
                                         NULL,
                                         PAGE_READWRITE,
                                         0,    
                                         sizeof(SMTEST),    
                                         "JJBSMTEST");   
 if(hMapF==NULL)
 {
  printf("CreateFileMapping() fail");
  return 1;
 }
 psm=(SMTEST *)MapViewOfFile(hMapF,FILE_MAP_ALL_ACCESS,0,0,sizeof(SMTEST));
//이후부터 psm 포인터만 읽으면 파일의 내용을 자유롭게 액세스할 수 있다. 
// 파일이 프로세스의 주소 공간에 맵되어 있으므로 포인터를사용하면 연결된 파일의 원하는 부분을 읽을 수 있다.

 psm->c='a';
 psm->i=100;
 psm->s=10;

 

//아래 프로그램을 실행할수있게 시간을 주자

 Sleep(10000);
 
 UnmapViewOfFile(psm);

 CloseHandle(hMapF);

 return 0;
}

  

<예제>

<공유메모리에 접근하여 데이터를 출력하는 프로그램.>

#include <windows.h>
#include <stdio.h>

#pragma pack(1)

typedef struct tag_SMTEST
{
 char c;
 int  i;
 short s;
} SMTEST;


int main(int argc, char *argv[])
{
 HANDLE hMapF;
 SMTEST *psm;

// JJBSMTEST라는 이름으로 공유메모리에 접근한다.

 hMapF=OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, "JJBSMTEST");
 
 if(hMapF==NULL)
 {
  printf("OpenFileMapping() fail");
  return 1;
 }
 psm=(SMTEST *)MapViewOfFile(hMapF,FILE_MAP_ALL_ACCESS,0,0,sizeof(SMTEST));

 

 //공유메모리에 설정된 내용을 출력한다.
 printf("c:%c i:%d, s:%d\n",psm->c,psm->i,psm->s);
 
 UnmapViewOfFile(psm);

 CloseHandle(hMapF);

 return 0;
}

<예제> 파일을 메모리에 올려놓고 마음대로 불러다 쓴다.

typedef struct Member
{
 char Id[256];
 char name[256]; 
}Member;


Member * member;
Member mem[1000];

void Init()
{

 int i=0;
  
 for(i=0; i<1000; i++)
 {
  strcpy(mem[i].Id,   "22");
  strcpy(mem[i].name,   "22");
 }
}


void FileSet()
{
 DWORD dwWritten;
 
 
 hFile = CreateFile("c:\\jinyong.dat", GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
 
 if(hFile!=INVALID_HANDLE_VALUE)
 {
  WriteFile(hFile, mem, sizeof(Member)*1000, &dwWritten, 0);
 }
 
 CloseHandle(hFile);
}


void Mapping()
{
 HANDLE hFile2;

 int i=0;
 hFile2 = CreateFile("c:\\jinyong.dat", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
 if(hFile2 != INVALID_HANDLE_VALUE)
 {
  hMap = CreateFileMapping(hFile2, NULL, PAGE_READWRITE, 0, 0, NULL);
  member = (Member *)MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
 }
 printf("%s\n",member[2].Id);
 printf("%s\n",member[3].name);

}
 

'API & MFC > API & 시스템프로그래밍' 카테고리의 다른 글

레지스트리  (0) 2010.02.02
o/s의 role  (0) 2010.01.28
파일매핑예제  (0) 2010.01.25
WNDCLASS 구조체  (0) 2010.01.25
스레드의 함정  (0) 2010.01.25
스레드  (0) 2010.01.24
Posted by 아몰라

댓글을 달아 주세요

 typedef struct tagWNDCLASS
{
      UNIT style;
      WNDPROC lpfnWndProc;
      int cbClsExtra;
      int cbWndExtra;
      HINSTANCE hInstace;
      HICON hIcon;
      HCURSOR hCursor;
      HBRUSH hbrBackground;
      LPCSTR lpszMenuName;
      LPCSTR lpszClassName;
}WNDCLASS;

lpszClassName - 등록하고자 하는 윈도우 클래스의 이름을 나타내는 문자열이며 윈도우 클래스의 구분에 사용된다.

hInstace - 윈도우 클래스를 등록한 응용 프로그램의 인스턴스 핸들이다. 이 멤버가 지정한 응용 프로그램이 이 윈도우 클래스의 소유주가 되며 소유주가 파괴되면 윈도우 클래스도 같이 파괴된다. 메인 윈도우를 만들 때는 WinMain으로 전달된 hHinstance 인수를 그대로 대입하면 된다.


lpfnWndProc - 메시지 처리 함수를 지정한다. 이 클래스로부터 만들어진 윈도우에 메시지가 전달되면 이 멤버가 지정하는 함수로 메시지가 전달되어 윈도우 고유의 처리를 하게 된다. 메인 윈도우 하나로 구성된 프로그램이라면 이 멤버의 값은 선택의 여지없이 WndProc이 될 것이나 차일드 윈도우나 팝업 윈도우가 있다면 다른 이름이 될 수도 있다.

hCursor - 클래스 커서를 지정한다. 이 클래스로부터 만들어진 윈도우의 작업영역에 마우스가 위치해 있을 때 이 멤버가 지정하는 커서가 사용된다. 리소스에 커서를 추가하고 LoadCursor 함수로 읽어 커서 핸들을 대입하거나 디폴크 커서 중 하나를 대입한다.

hIcon - 타이틀 바의 좌상단에 보여줄 아이콘과 윈도우가 최소화되었을 때 보여줄 아이콘을 지정한다. NULL일 경우 아이콘을 그려야할 때 운영체제가 WM_ICONERASEBKGND 메시지를 보내는데 이 때 원하는 아이콘을 직접 그려야한다.

hbrBackground - 윈도우의 작업영역을 칠할 배경 브러시를 지정한다. GetStockObject나 그 외 브러시를 만드는 함수를 사용하여 브러시 핸들을 얻은 후 이 멤버에 대입한다.

lpszMenuName -  이 클래스로부터 만들어진 윈도우가 사용할 메뉴를 지정한다.

style - 윈도우 클래스의 스타일을 지정한다. CreateWindow 에서 지정하는 개별 윈도우의 스타일과는 다르지만 결국은 이 클래스로부터 만들어지는 윈도우에 영향을 미친다.

cbClsExtra - 윈도우 클래스에서 사용하고자 하는 여분의 메모리양을 바이트 단위로 지정한다. 운영체제는 윈도우 클래스를 등록할 때 이 멤버가 지정하는만큼의 메모리를 추가로 할당한다.

cbWndExtra - cbClsExtra와 유사하되 개별 윈도우에서 사용하고자 하는 여분의 메모리양을 지정한다. 운영체제는 CreateWindow로 개별 윈도우를 만들 때마다 이 멤버가 지정하는만큼의 메모리를 추가로 할당한다.

출처 - 윈도우즈 API 정복 , 김상형 지음

'API & MFC > API & 시스템프로그래밍' 카테고리의 다른 글

o/s의 role  (0) 2010.01.28
파일매핑예제  (0) 2010.01.25
WNDCLASS 구조체  (0) 2010.01.25
스레드의 함정  (0) 2010.01.25
스레드  (0) 2010.01.24
이벤트  (0) 2010.01.24
Posted by 아몰라

댓글을 달아 주세요

이전버튼 1 2 3 이전버튼