[WINAPI] 콘솔 창 띄우고 싶을 때

- api에서 값 확인 하고 싶을 때

간편하게 콘솔 창 띄울 수 있는 방법

main위에 추가하기!


- 디버그 모드에서만 콘솔 창이 뜬다.



#ifdef _DEBUG

#pragma comment(linker, "/entry:WinMainCRTStartup /subsystem:console")

#endif


'c/c++ > winapi' 카테고리의 다른 글

HINSTANCE HWND 차이  (0) 2012.11.26
메시지 박스 최상위로 뜨게  (0) 2012.11.21
[API] 여러 가지 출력 - 그래픽  (0) 2012.08.02
[API]OWNERDRAW로 버튼 이미지 바꾸기  (0) 2012.08.01
[API] 슬라이더에서 값 읽어오기  (0) 2012.07.23

[API] 여러 가지 출력 - 그래픽

COLORREF SetPixel(hdc, nXPos, nYPos, clrref)
DWORD MoveToEx(hdc, x, y, lpPoint)
BOOL LineTo(hdc, xEnd, yEnd)
BOOL Rectangle(hdc, nLeftRect, nTopRect, nRightRect, nBottomRect)
BOOL Ellipse(hdc, nLeftRect, nTopRect, nRightRect, nBottomRect)

[API]OWNERDRAW로 버튼 이미지 바꾸기

SendMessage()를 이용하여 버튼 이미지를 변경해 주면,

EnableWindow()로 버튼을 비활성화 시킬 경우 버튼이 회색으로 변해버린다.

 

이 문제를 해결하기 위해 버튼에 BS_OWNERDRAW 스타일을 추가하여

직접 이미지를 그려준다.

 

1. 버튼 생성

case WM_CREATE:

  CreateWindow("button","",WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | BS_BITMAP | BS_OWNERDRAW,
   100,100,70,30,hWnd,(HMENU)IDC_BUTTON, hInst,NULL);


도구 상자를 이용하여 버튼을 추가했을 경우 속성에 Owner Draw 값을 True로 설정해주어야 한다. 

안해주면 WM_DRAWITEM 이벤트가 안옴




 

2. 이미지 로드

hBitmap[0] = LoadBitamp(hInst, MAKEINTRESOURCE(IDB_BITMAP1));

hBitmap[1] = LoadBitamp(hInst, MAKEINTRESOURCE(IDB_BITMAP2));

 

3. 이미지를 그려 줄 구조체, 변수 선언

 static LPDRAWITEMSTRUCT lpdis;
 static HDC memDC;

4. case WM_DRAWITEM에서 이미지 그려줌 

 case WM_DRAWITEM:
  lpdis = (LPDRAWITEMSTRUCT)lParam;

  if(lpdis->itemState & ODS_SELECTED) // 버튼이 눌린 상태(BUTTONDOWN)
  {
   memDC = CreateCompatibleDC(lpdis->hDC);
   SelectObject(memDC,hBitmap[1]);
   BitBlt(lpdis->hDC, 0,0,100,50,memDC,0,0,SRCCOPY);
   DeleteDC(memDC);
  }
  else // 버튼이 UP되어 있는 상태(BUTTONUP)
  {
   memDC = CreateCompatibleDC(lpdis->hDC);
   SelectObject(memDC,hBitmap[0]);
   BitBlt(lpdis->hDC, 0,0,100,50,memDC,0,0,SRCCOPY);
   DeleteDC(memDC);
  }
  break;

 

- 버튼을 눌렀을 때와, 누르지 않고 있을 때 이미지 변경

 

 

 

 

/************************* 참고

* Owner draw의 값으로 여러 경우에서 버튼 이미지를 변경 가능 하다 

*/

#define ODS_SELECTED 0x0001

#define ODS_GRAYED 0x0002

#define ODS_DISABLED 0x0004

#define ODS_CHECKED 0x0008

#define ODS_FOCUS 0x0010

#if(WINVER >= 0x0400)

#define ODS_DEFAULT 0x0020

#define ODS_COMBOBOXEDIT 0x1000

#endif /* WINVER >= 0x0400 */

#if(WINVER >= 0x0500)

#define ODS_HOTLIGHT 0x0040

#define ODS_INACTIVE 0x0080

#endif /* WINVER >= 0x0500 */



 

//3. static LPDRAWITEMSTRUCT lpdis; static HDC memDC; static HBITMAP hBitmap[2]; switch (message) { //1. case WM_CREATE: CreateWindow("button","",WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | BS_BITMAP | BS_OWNERDRAW, 100,100,70,30,hWnd,(HMENU)IDC_BUTTON, hInst,NULL); //2. hBitmap[0] = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP1)); hBitmap[1] = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP2)); break; //4. case WM_DRAWITEM: lpdis = (LPDRAWITEMSTRUCT)lParam; if(lpdis->itemState & ODS_SELECTED) // 버튼이 눌린 상태(BUTTONDOWN) { memDC = CreateCompatibleDC(lpdis->hDC); SelectObject(memDC,hBitmap[1]); BitBlt(lpdis->hDC, 0,0,100,50,memDC,0,0,SRCCOPY); DeleteDC(memDC); } else // 버튼이 UP되어 있는 상태(BUTTONUP) { memDC = CreateCompatibleDC(lpdis->hDC); SelectObject(memDC,hBitmap[0]); BitBlt(lpdis->hDC, 0,0,100,50,memDC,0,0,SRCCOPY); DeleteDC(memDC); } break;             }


[API] 슬라이더에서 값 읽어오기

1.  슬라이더 핸들 가져오기

GetDlgItem(); 

 

2. 범위 설정 // 5단계 (0,1,2,3,4)

SendMessage(hdlg, TBM_SETRANGE, FALSE, MAKELPARAM(0,4));

 

3. 값 가져오기 // pos에 슬라이더 값 저장

int pos = SendDDlgItemMessage(hDlg,IDC_SLIDER1,TBM_GETPOS,0,0);

- 슬라이더가 세로일 경우에는  case WM_VSCROLL: 에서 값을 가져오고

                    가로 일 경우에는 case WM_HSCROLL: 에서 값을 가져온다 

 

4. 읽어온 값 확인 // 에디트 박스 이용.

SetDlgItemInt(hDlg, IDC_EDIT1, pos+1, TRUE);

 

 

int pos=0;
	
	switch(message)
	{
	case WM_INITDIALOG:
		hDlg = GetDlgItem(hDlg,IDC_SLIDER1);
		SendMessage(hDlg,TBM_SETRANGE,FALSE,MAKELPARAM(0,4));
		break;
	
	case WM_VSCROLL:	
			pos = SendDlgItemMessage(hDlg,IDC_SLIDER1,TBM_GETPOS,0,0);
			SetDlgItemInt(hDlg,IDC_EDIT1,pos+1,TRUE);
		break;
	case WM_COMMAND:
		switch(LOWORD(wParam))
		{
		case IDOK:
			PostQuitMessage(0);
		case IDCANCEL:
			EndDialog(hDlg,LOWORD(wParam));
			break;
		}
		break;
	}
	return 0;

'c/c++ > winapi' 카테고리의 다른 글

[API] 여러 가지 출력 - 그래픽  (0) 2012.08.02
[API]OWNERDRAW로 버튼 이미지 바꾸기  (0) 2012.08.01
[API] 버튼에 이미지 씌우기  (0) 2012.07.23
Win32 API에 버튼 추가하기  (0) 2009.11.07
WM_TIMER  (0) 2009.05.26

[API] 버튼에 이미지 씌우기

API로 이미지로 된 버튼을 만들고 싶어서

맨 처음에는 CreateWindow로 버튼을 만들었는데 이제는 도구박스로도 만들 수 있다 헤헤

그냥 SendMessage로 이미지만 전달해주면 오케이~

 

 

1. 리소스에 버튼에 그려줄 비트맵 저장

 

2. 리소스에 저장된 이미지를 불러온다.

LoadBitmap 함수를 이용하여 HBITMAP 구조체에 비트맵을 저장

 

3. 버튼을 생성한다 (도구 상자를 이용하여 버튼 생성시 속성에서 Bitmap TRUE로) 

(CreateWindow로 이용할 경우에도 속성에 BS_BITMAP을 추가하여 설정 할 수 있다.)

 

 

 

 

4. 버튼의 핸들을 구한다.

GetDlgItem 함수로  

5. 이미지를 보낸다.

SendMessage( 4번에서 구한 핸들 값, BM_SETIMAGE, 0, (LPARAM)저장한 비트맵)

 

 

 

 

 

HBITMAP hBitmap;

HWND hDlg;

 

switch(message)

{

 

case WM_CREATE:

hBitmap = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP1)); // 비트맵 읽어온다

hDlg = GetDlgItem(hDlg, IDC_BUTTON1); // 버튼의 핸들 구하기

SendMessasge(hDlg, BM_SETIMAGE, 0, (LPARAM)hBitmap); // 버튼에 이미지 씌운다

break;

 

}

 

 

 

 

저 튤립과 국화랑 등대였나...가

버튼 이미지가 되었당 짜란~

'c/c++ > winapi' 카테고리의 다른 글

[API]OWNERDRAW로 버튼 이미지 바꾸기  (0) 2012.08.01
[API] 슬라이더에서 값 읽어오기  (0) 2012.07.23
Win32 API에 버튼 추가하기  (0) 2009.11.07
WM_TIMER  (0) 2009.05.26
ComboBox  (0) 2009.05.26

Win32 API에 버튼 추가하기

 

  1. 메인 소스 맨 위쪽의 define 부분에 추가할  버튼 컨트롤 ID추가

     #define IDC_SEND 1003 //버튼컨트롤 ID
    ※위의 버튼 컨트롤은 1002번으로 계속 버튼 컨트롤 숫자를 1씩 추가

  2. WndProc 함수에 버튼을 눌렀을 경우 해당하는 내용 추가

     
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
          int wmId, wmEvent;
          PAINTSTRUCT ps;
          HDC hdc;
          static SHACTIVATEINFO s_sai;

           switch (message) 
           {
                  case IDC_SEND:
                                   bt.PortWrite(L"12345");
                                   break;

     →IDC_SEND 버튼을 눌렀을때 나타는 일은 PortWrite 함수를 호출하는 것. 

  3. 화면에 버튼 그려주기
                  case WM_CREATE:
                                CreateWindow(L"button", L"SendButton",WS_CHILD| WS_VISIBLE|BS_PUSHBUTTON,
                                                     10,160,100,30,hWnd,(HMENU)IDC_SEND,g_hInst,NULL);
                                break;
     위의 switch 문에 이어서 WMCREATE 부분에 CreateWindow함수를 추가하는 것으로 화면에 버튼이 만들어진다.
    이것은 단순히 화면에 버튼만 출력하는 것으로, 이 부분만 수행하였다면  2번째 과정을 안했으므로 버튼을 클릭하여도 아무런 반응이 없을 것이다, 아니면 아에 컴파일이 안되는건가.

    - CreateWindow 함수에서 버튼을 만드는데 쓰이는 파라미터는 빨간색으로 표시해 놨으며,
        그 부분에 대하여 설명을 하자면,  

           
                    L"button" :  버튼을 만든 다
                    L"SendButton" : 버튼 안에 들어갈 문자 
                    10,160,100,30 : 버튼이 생성될 위치와 크기 
                                         x좌표, y좌표,  수평크기, 수직크기
                    IDC_SEND : 버튼 컨트롤 ID

    ※ 버튼의 모양을 바꾸기 위해서는 WS_CHILD| WS_VISIBLE|BS_PUSHBUTTON 이 부분에 해당하는 내용을 변경 하여야 한다.





     

'c/c++ > winapi' 카테고리의 다른 글

[API]OWNERDRAW로 버튼 이미지 바꾸기  (0) 2012.08.01
[API] 슬라이더에서 값 읽어오기  (0) 2012.07.23
[API] 버튼에 이미지 씌우기  (0) 2012.07.23
WM_TIMER  (0) 2009.05.26
ComboBox  (0) 2009.05.26

WM_TIMER

시간과 관련된 함수들을 사용할 것이므로 프로그램 선두에 time.h를 포함시켜 두었다. 

WndProc의 선두에는 시간값을 저장할 time_t형의 변수 mytime과 이 시간값을 문자열로 변경하여 저장할 str, 그리고 타이머 핸들인 hTimer 세 개의 변수가 선언되어 있다.

 WM_CREATE 메시지에서 SetTimer 함수를 사용하여 타이머를 생성시켰다. 즉 윈도우가 만들어지자 마자 타이머가 만들어진다.
( WM_CREATE 메시지는 윈도우가 처음 생성될 때 발생하는데 이 메시지에서 프로그램 시작시 꼭 한번만 초기화되어야 할 처리를 해 준다. )

 UNIT SetTimer(HWND hWnd, UINT nIDEvent, UINT uElapse, TIMERPROC lpTimerFunc)


hWnd 인수는 타이머 메시지를 받을 윈도우인데 통상 WndProc의 인수로 전달되는 hWnd를 그대로 써 주면 된다. 두번째 인수 nIDEvent는 타이머의 번호를 지정한다. 하나의 타이머만 사용할 경우 1을 주면 되며 여러개의 타이머를 사용할 경우 nIdEvent에 겹치지 않도록 번호를 부여하도록 한다. 예를 들어 세개의 타이머를 사용한다면 각각 1, 2, 3의 타이머 번호를 주면 되며 이 타이머 번호는 WM_TIMER 메시지에서 타이머를 구분하기 위한 표식으로 사용된다.

세번째 인수 uElapase는 1/1000초 단위로 타이머의 주기를 설정한다. 이 값이 1000이면 타이머 메시지가 1초에 한번씩 hWnd로 보내지게 될것이고 10000이면 10초에 한번씩 타이머 메시지가 발생할 것이다. 네번째 인수는 타이머 메시지가 발생할 때마다 호출될 함수를 지정하는데 사용하지 않을 경우 NULL로 설정하면 된다.

WM_TIMER 메시지는 wParam으로 타이머 ID를 전달받으며 lParam으로 타이머 메시지 발생시 호출될 함수의 번지가 전달된다. 이 예제에서는 타이머가 하나밖에 없으며 타이머 메시지 처리 함수도 지정되지 않았으므로 둘 다 무시하고 사용하지 않는다. WM_TIMER 메시지가 발생하면 time 함수로 시간을 조사한 후 ctime 함수로 문자열로 바꾼후 문자열 str에 저장해 둔다. 두 함수의 원형은 다음과 같다.

time_t time( time_t *timer ); char *ctime( const time_t *timer );

time 함수는 현재 시간을 조사해 주는데 이 때 조사되는 값은 1970년 1월 1일 자정 이후 경과한 초이며 조사된 값은 인수로 전달된 time_t형의 변수에 대입되며 동시에 리턴값으로도 전달된다. 만약 오늘이 1998년 1월 1일 0시라면 조사되는 값은 31536000*28이 될 것이다. 이렇게 조사된 시간값은 ctime 함수에 의해 문자열로 변경된다. ctime은 time_t값으로부터 현재 날짜와 시간을 계산하여 정확하게 문자열로 변경해 주며 그 문자열을 리턴해 준다.

예제에서는 mytime이라는 time_t형의 변수에 시간값을 조사한 후 이 값을 문자열로 변경하여 str 문자열 포인터에 대입하였다. 이제 남은 일은 조사된 시간을 화면으로 출력하는 것이다. WM_TIMER에서는 시간이 갱신될 때마다 화면을 갱신시키기 위해 InvalidateRect 함수를 호출하고 있다.

마지막으로 해 주어야 할 일은 WM_DESTROY 메시지에서 설치된 타이머를 제거해 주는 것이며 이 때는 KillTimer 함수를 사용한다.

 BOOL KillTimer( HWND hWnd, UINT uIDEvent );

KillTimer의 첫번째 인수로 이 타이머를 소유한 윈도우 핸들을 넘겨주며 두번째 인수로 타이머 ID를 넘겨준다. 주의할 것은 타이머 ID는 SetTimer의 두번째 인수로 지정한 값을 말하는 것이지 SetTimer가 리턴한 값을 말하는 것이 아니라는 점이다. 이 예제에서는 SetTimer에서 타이머 ID를 1이라는 상수로 주었으므로 파괴할 때도 타이머 ID로 상수 1을 넘겨 주어야 한다. SetTimer의 리턴값은 타이머를 소유하는 윈도우 없이 타이머가 만들어졌을 경우, 즉 SetTimer의 첫번째 인수가 NULL일 경우에 한해 특별하게 사용하는 것이되 거의 사용되지 않는다고 보면 된다.



'c/c++ > winapi' 카테고리의 다른 글

[API]OWNERDRAW로 버튼 이미지 바꾸기  (0) 2012.08.01
[API] 슬라이더에서 값 읽어오기  (0) 2012.07.23
[API] 버튼에 이미지 씌우기  (0) 2012.07.23
Win32 API에 버튼 추가하기  (0) 2009.11.07
ComboBox  (0) 2009.05.26

ComboBox

콤보박스에 아이템 추가는 Dialog에서 combo Box 선택후 Properties에서 Data탭에서 추가 다음아이템으로 넘어가는거 ctrl+Enter
styles 탭에서 sort하지 말자 ..ㅋ


아이템 추가한거 이용하기

1. ctrl + W -> member variable탭에서  IDC_COMBO 의 type은 CCombo로 ㄱㄱㄱㄱㄱㄱㄱㄱㄱ


2.버튼 눌러서? 아직은 여기까지밖에 ㅠㅠ
int형 변수 추가해서 GetCurSel()이용하면 변수에 아이템 순서에 따라 정수 0,1,2,3... 중에 하나 저장됨
그래서 switch case 문으로 내가 원하는 것 이용

void CMy1Dlg::OnButton0()
{
 // TODO: Add your control notification handler code here
 int n = m_cbListItem.GetCurSel();

 switch(n)
 {
 case 0:
  AfxMessageBox("더하기더해");
  break;
 case 1:
  AfxMessageBox("빼기");
  break;
 case 2:
  AfxMessageBox("곱하기");
  break;
 case 3:
  AfxMessageBox("나누기");
  break;
 }
}


'c/c++ > winapi' 카테고리의 다른 글

[API]OWNERDRAW로 버튼 이미지 바꾸기  (0) 2012.08.01
[API] 슬라이더에서 값 읽어오기  (0) 2012.07.23
[API] 버튼에 이미지 씌우기  (0) 2012.07.23
Win32 API에 버튼 추가하기  (0) 2009.11.07
WM_TIMER  (0) 2009.05.26