[Win32 API] DialogBoxParam

Projects/CoVNC 2007.05.20 19:45 Posted by soulfree >동네청년<

DialogBoxParam



   원 형       INT_PTR DialogBoxParam(HINSTANCE hInstance, LPCTSTR lpTemplateName,

                                  HWND hWndParent, DLGPROC lpDialogFunc, LPARAM dwInitParam);


   설 명       대화상자 대부분이 비슷하고 일부분만 조금 다른 대화상자가 여러 개 필요한 경우가 있다.

                 예를 들어 저장을 위한 파일명과 읽기를 위한 파일명을 입력받는 대화상자 둘은 안내 메시지 정도만 다를 뿐 필요한 컨트롤이나 동작방식은 거의 유사하다. 에러 메시지 출력 대화상자도 에러 메시지 정도만 다르고 나머지는 거의 유사할 것이다. 이런 경우는 하나의 대화상자만 만들어 두고 필요할 때마다 대화상자의 동작방법을 조금씩 바꿔가면 사용하면 된다.


그 해결방법으로 가장 쉽게 떠오르는 것은 전역변수를 사용하는 것이다. 대화상자를 부르기 전에 전역변수에 값을 대입하고 대화상자는 이 전역변수의 값에 따라 조금씩 다르게 동작하도록 프로그래밍하면 된다. 이 방법도 물론 원론적으로 문제가 없으며 실전에서도 자주 활용되지만 대화를 위해 전역변수를 남발하는 것은 별로 바람직하지 않다. 좀 더 좋은 방법은 부모 윈도우가 대화상자를 호출할 때 파라미터를 전달하고 대화상자는 파라미터를 해석해서 동작 방법을 결정하는 방법이다. 이때 DialogBoxParam 함수가 사용된다.


함수 원형은 DialogBox 와 거의 유사하되 제일 뒤에 dwInitParam 이라는 인수가 하나 더 추가되어 있다. 이 값은 대화상자를 생성할 때 WM_INITDIALOG 의 lParam 으로 전달된다. 파라미터는 32비트의 정수값이지만 포인터를 전달할 수도 있으므로 구조체나 메모리 핸들같은 큰 데이터도 얼마든지 전달할 수 있다.

 

참조 함수    DialogBox

신고
TAG C++, Win32 API

API에서 HINSTANCE와 HWND에 대한 질문입니다.

Projects/CoVNC 2006.11.08 22:48 Posted by soulfree >동네청년<

안녕하세요. API에 대해 공부하고 있는 학생입니다.


공부를 하던 중 궁금한 점이 있어서 이렇게 질문을 드립니다.


다름이 아니고..


왜 HINSTANCE(프로그램을 구별하기 위한 핸들)과 HWND(윈도우를 구별하기 위한 핸들)


을 왜 나누는것이죠? 차라리 하나를 합치는게 출력할때 더 편하지 않을까요? 어떤 윈도우


에대가 출력해라가 아니라.. 어떤 프로그램에 출력해라가 더 좋지 않나요? 굳이 HWND를


사용할 필요가 있나요? 아니면 하나의 프로그램에 하나의 윈도우가 아니라 하나의 프로그


램에 다수의 윈도우에다가 출력할려고 그러는건가요? 만약 그렇다면... 예좀 들어주십시요


.. 제가 이해가 잘못되어서인지 잘 모르겠습니다. 복잡하게 질문을 드렸는데.. 제가 초보라


서 그렇습니다.. 황당한 질문이시겠지만 답변을 주시면 감사하겠습니다

질문자가 선택한 답변 
re: API에서 HINSTANCE와 HWND에 대한 질문입니다. 

theuhm (2005-10-18 23:43 작성) 
이의제기 | 신고

질문자 평
감사합니다^^ 

우선 한가지 오해가 있습니다.

HINSTANCE는 프로그램의 핸들이 아닙니다. HINSTANCE는 프로그램 코드를 담고 있는 모듈에 대한 핸들이죠. 즉, 프로그램이 수행되려면, 프로그램 코드를 담고 있는 파일을 메모리의 특정 영역에 올려서 명령을 하나씩 읽어가면서 수행할 수 있도록 준비해 놓아야 합니다. 이렇게 메모리에 올려진 프로그램 코드 덩어리를 윈도우에서 관리하기 위해서 일종의 고유 식별 번호를 부여하는데, 이것이 인스턴스핸들, HINSTANCE입니다. 기본적으로 프로세스를 실행하는 실행파일의 코드를 메모리에 올려놓은 모듈이 하나 있어야 하므로, 실행파일의 모듈에 대한 인스턴스 핸들을 OS가 어플리케이션에 WinMain의 인자로 넘겨주는 것입니다.

한 프로세스가 여러개의 모듈을 로딩하여 프로그램을 실행하고 있다면 하나의 프로그램이 여러개의 인스턴스 핸들을 할당받아 쓰고 있을 수가 있습니다. (물론 한 개의 모듈을 여러 프로세스가 공유하고 있을 수도 있습니다) 대표적인 예가 바로 IE입니다. 간단하게, DLL파일 한개를 쓸 때마다 이 DLL모듈에 대한 인스턴스 핸들이 한개씩 생긴다고 보시면 됩니다. 물론 DLL이 한번 로딩되면 다른 프로그램 사이에서 공유된다는 점은 알고 계시리라 믿습니다.


한개의 프로그램에서 HINSTANCE가 한 개만 있는 것이 아니며, 또한 하나의 인스턴스핸들이 한개의 프로그램에만 종속되는 것이 아니므로, 어떤 프로그램의 출력 대상을 지정하는 데에는 부적절하다는 점을 알 수 있을 겁니다. 물론, 인스턴스 핸들은 애초부터 화면 출력을 고려하여 만들어진 식별자는 아닙니다. 인스턴스 핸들은 단지 프로그램 코드 덩어리를 관리하기 위해 만들어진 리소스입니다.



윈도우라는 OS에서 화면 출력을 위해 관리하는 리소스가 바로 윈도우핸들입니다. MSN메신저등을 보시면 알겠지만, 하나의 프로그램이 하나의 창을 사용한다는 보장이 없습니다. 오히려 99.99%의 프로그램은 한 개 이상의 윈도우로 구성되어 있습니다. 지금 쓰고 계실 것으로 추정되는 IE역시  메뉴바, 툴바, 하단 상태바, 주소창 등등이 모두 별개의 윈도우입니다. 물론 가장 바깥쪽의 프레임 윈도우와, 내부에 웹문서를 보여주는 클라이언트 윈도우도 따로 존재합니다. 즉, 한 프로그램의 윈도우가 겉보기에는 단일한 대상 영역으로 보일지라도, 실제로는 구성요소별로 분리하여 별개의 윈도우로 만들어 각 윈도우는 자기 자신이 맡은 부분에 대한 화면 출력과 사용자 입력만을 담당합니다. 자연히 하나의 프로그램에서 사용하는 윈도우핸들, HWND타입의 개체 역시 1개 이상이 될 수밖에 없으며, 이러한 상황에서 특정 위치에 특정한 동작을 수행하기 위해서는 HWND로 대상 영역을 구분할 수밖에 없는 것이죠.

신고

Win32 API reference

Projects/CoVNC 2006.11.06 12:47 Posted by soulfree >동네청년<
신고
TAG C++, Win32 API

win32 API를 이용한 file dialog 띄우기 예제

Projects/CoVNC 2006.11.05 02:49 Posted by soulfree >동네청년<

#include <windows.h>

LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
HINSTANCE g_hInst;
LPSTR lpszClass="FODial";

int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance
  ,LPSTR lpszCmdParam,int nCmdShow)
{
HWND hWnd;
MSG Message;
WNDCLASS WndClass;
g_hInst=hInstance;

WndClass.cbClsExtra=0;
WndClass.cbWndExtra=0;
WndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
WndClass.hCursor=LoadCursor(NULL,IDC_ARROW);
WndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
WndClass.hInstance=hInstance;
WndClass.lpfnWndProc=(WNDPROC)WndProc;
WndClass.lpszClassName=lpszClass;
WndClass.lpszMenuName=NULL;
WndClass.style=CS_HREDRAW | CS_VREDRAW;
RegisterClass(&WndClass);

hWnd=CreateWindow(lpszClass,lpszClass,WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,
NULL,(HMENU)NULL,hInstance,NULL);
ShowWindow(hWnd,nCmdShow);

while(GetMessage(&Message,0,0,0)) {
TranslateMessage(&Message);
DispatchMessage(&Message);
}
return Message.wParam;
}

LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
OPENFILENAME OFN;
char str[300];
char lpstrFile[MAX_PATH]="";
switch(iMessage) {
case WM_LBUTTONDOWN:
memset(&OFN, 0, sizeof(OPENFILENAME));
OFN.lStructSize = sizeof(OPENFILENAME);
OFN.hwndOwner=hWnd;
OFN.lpstrFilter="Every File(*.*)\0*.*\0Text File\0*.txt;*.doc\0";
OFN.lpstrFile=lpstrFile;
OFN.nMaxFile=256;
OFN.lpstrInitialDir="c:\\";
if (GetOpenFileName(&OFN)!=0) {
  wsprintf(str,"%s 파일을 선택했습니다.",OFN.lpstrFile);
  MessageBox(hWnd,str,"파일 열기 성공",MB_OK);
}
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return(DefWindowProc(hWnd,iMessage,wParam,lParam));
}


신고