본문 바로가기
코스웨어/15년 스마트컨트롤러

20151117 임현수 업무일지 WIN32API #4

by 알 수 없는 사용자 2015. 11. 18.
728x90
반응형
■ WIN32API


■ 엑셀러레이터(단축키)



▲ 메뉴의 캡션을 위와같이 수정한다.
menu&1\tCtrl+A
menu&2\tCtrl+B
&exit\tCtrl+C

▲ 엑셀러레이터 리소스를 추가해 위와같이 키셋팅을 한다.

▲ 소스코드를 위와같이 수정한다.

■ 문자열테이블

문자열 테이블은 프로그램 내에서 사용하는 대부분의 문자열을 등록시켜놓는 테이블이다.
문자열들을 테이블에 모아서 따로 관리할 수 있기 때문에, 관리가 편하다.




■ GDI 오브젝트

선모양이나 선색깔을바꿀 수 있는 항목이다.

비트맵 그릴수도잇고 
윈도우가 제공하는건 무언가를 그릴수있게 도와주는거랑, 읽어와서 집어넣는거.


■ 스톡 오브젝트


▲ 기존브러시는 나중에 다시 되돌려주기 위해 oldBrush에 저장한다.
SelectObject는 펜을 바꿔잡는 개념으로 보면된다.


■ 펜


펌웨어는 레지스터 사용방법을 읽히는게 핵심이고
api는 함수 활용방법을 익히는게 핵심이다.

C가 기반이 되었기 때문에 win32 api를 짤수있다.

C++

+ MFC구조

MFC App

펌웨어에 UI가 필요하면 win32 api 정도까지만 배우면 문제될거 없다.

펜은 동적할당받기때문에 delete해서 지워줘야한다.

LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
  HDC hdc;
  PAINTSTRUCT ps;
  HBRUSH myBrush;
  HBRUSH oldBrush;
  HPEN myPen;
  HPEN oldPen;

  switch (iMessage)
  {
  case WM_DESTROY:
    PostQuitMessage(0);
    return 0;

  case WM_PAINT:
    hdc = BeginPaint(hWnd, &ps);

    myBrush = (HBRUSH)CreateHatchBrush(HS_FDIAGONAL, RGB(255,255,0));
    oldBrush = (HBRUSH)SelectObject(hdc, myBrush);
    
    myPen = CreatePen(PS_DOT, 5, RGB(25500));
    oldPen = (HPEN)SelectObject(hdc, myPen);

    Rectangle(hdc, 5050300200);

    SelectObject(hdc, oldBrush);
    SelectObject(hdc, oldPen);
    DeleteObject(myPen);
    DeleteObject(myBrush);

    EndPaint(hWnd, &ps);
    return 0;

  }
  return(DefWindowProc(hWnd, iMessage, wParam, lParam));
}


그리기

선을 긋고나서 기존선을 지우기위해 XOR연산을 하면 된다.


LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
  HDC hdc;
  PAINTSTRUCT ps;

  static int sx;
  static int sy;
  static int oldx;
  static int oldy;
  int ex;
  int ey;
  static BOOL bNowDraw = FALSE;

  switch (iMessage)
  {
  case WM_DESTROY:
    PostQuitMessage(0);
    return 0;

  case WM_LBUTTONDOWN:
    sx = LOWORD(lParam);
    sy = HIWORD(lParam);
    oldx = sx;
    oldy = sy;
    bNowDraw = TRUE;
    return 0;

  case WM_LBUTTONUP:
    bNowDraw = FALSE;
    hdc = GetDC(hWnd);
    MoveToEx(hdc, sx, sy, NULL);
    LineTo(hdc, oldx, oldy);
    ReleaseDC(hWnd, hdc);
    return 0;

  case WM_MOUSEMOVE:
    if (bNowDraw)
    {
      hdc = GetDC(hWnd);
      //SetROP2(hdc, R2_NOT);
      MoveToEx(hdc, sx, sy, NULL);
      LineTo(hdc, oldx, oldy);
      ex = LOWORD(lParam);
      ey = HIWORD(lParam);
      MoveToEx(hdc, sx, sy, NULL);
      LineTo(hdc, ex, ey);
      oldx = ex;
      oldy = ey;
      ReleaseDC(hWnd, hdc);
    }
    return 0;

  }
  return(DefWindowProc(hWnd, iMessage, wParam, lParam));
}

▲ 주석친 SetROP2()함수를 주석해제하면 XOR연산을 하지않기 때문에 잔상이 그대로 남는다.

수학공식을 이용한 그리기

LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
  HDC hdc;
  PAINTSTRUCT ps;
  double f;
  int y;

  switch (iMessage)
  {
  case WM_DESTROY:
    PostQuitMessage(0);
    return 0;

  case WM_PAINT: 
    hdc = BeginPaint(hWnd, &ps);
    SetMapMode(hdc, MM_LOENGLISH);
    SetViewportOrgEx(hdc, 200150, NULL);
    MoveToEx(hdc, -20000, NULL);
    LineTo(hdc, 20000);
    MoveToEx(hdc, 0, -2000, NULL);
    LineTo(hdc, 02000);
    for (f = -500; f < 1000; f++)
    {
      y = (int)(sin(f*3.14 / 180) * 100);
      SetPixel(hdc, (int)f, y, RGB(000));
    }
    EndPaint(hWnd, &ps);
  }
  return(DefWindowProc(hWnd, iMessage, wParam, lParam));
}



■ 비트맵

bitblt함수로 실제로 화면에 표시한다.

LoadBitmap() 하면 메모리에 롤라간다.


0,0은 시작, 이미지 가로크기 세로크기

속도가 더딘데

나중에 올리는 작업을 wm_create에보내고
delete작업을 destroy에 보낸다.

그리고 중간에는 static으로 해놓으면 메모리에 계속 남아있는다.


그림한장을 만들고나면 
그래픽이 개입하면 무조건 느려진다.
이 방법을 쓰면 조금 개선될 수 있다.( 버퍼링)

loadBitmap해야 실제로 적재가된다.

BitBlt함수는 원본이미지를그대로 보여주는 함수이다.

이미지 확대 축소함수
StretchBlit

MemDC부분의 인자를 바꿔주면 확대 축소가 된다.


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

#define XMOV  8
#define YMOV  8
#define XTILE  48
#define YTILE  48

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

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_CAPTION|WS_MINIMIZEBOX|WS_SYSMENU,
    CW_USEDEFAULT,
    CW_USEDEFAULT,
    (700+36),
    (480+36),
    NULL,
    (HMENU)NULL,
    hInstance,
    NULL);
  ShowWindow(hWnd, nCmdShow);

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

LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
  HDC hdc;
  static HDC MemDC;

  PAINTSTRUCT ps;
  static int ixPos = 0;
  static int iyPos = 0;

  static int ixPos_Max;
  static int iyPos_Max;
  
  static RECT rt;
  RECT RtArea;

  static HBITMAP myBitmap;
  static HBITMAP oldBitmap;
  static HBITMAP backBitmap;

  static HBITMAP frontBitmap;
  static HBITMAP leftBitmap;
  static HBITMAP rightBitmap;
  static HBITMAP rearBitmap;

  int iCntX;
  int iCntY;

  switch (iMessage)
  {
    case WM_CREATE:
      hdc = GetDC(hWnd);

      MemDC = CreateCompatibleDC(hdc);
      frontBitmap = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_BITMAP3));
      leftBitmap = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_BITMAP5));
      rightBitmap = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_BITMAP6));
      rearBitmap = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_BITMAP7));
      backBitmap = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_BITMAP4));
      oldBitmap = (HBITMAP)SelectObject(MemDC, frontBitmap);
      
      GetClientRect(hWnd, &rt);
      ixPos_Max = rt.right;
      iyPos_Max = rt.bottom;

      myBitmap = frontBitmap;

      ReleaseDC(hWnd, hdc);
      return 0;

    case WM_DESTROY:
      SelectObject(MemDC, oldBitmap);
      DeleteObject(frontBitmap);
      DeleteObject(leftBitmap);
      DeleteObject(rightBitmap);
      DeleteObject(rearBitmap);
      DeleteObject(backBitmap);
      DeleteDC(MemDC);
      PostQuitMessage(0);
      return 0;

    case WM_PAINT:
      hdc = BeginPaint(hWnd, &ps);
      SelectObject(MemDC, backBitmap);
      for (iCntY = 0; iCntY < 10; iCntY++)
      {
        for (iCntX = 0; iCntX < 15; iCntX++)
        {
          BitBlt(hdc, (iCntX*48), (iCntY*48), 4848, MemDC, 00, SRCCOPY);
        }
      }
      
      SelectObject(MemDC, myBitmap);
      BitBlt(hdc, ixPos, iyPos, 4848, MemDC,00, SRCCOPY);
      EndPaint(hWnd, &ps);
      return 0;
      
    case WM_KEYDOWN:
      RtArea.top = iyPos;
      RtArea.bottom = iyPos + YTILE;
      RtArea.left = ixPos;
      RtArea.right = ixPos + XTILE;

      switch (wParam)
      {
      case VK_LEFT:
        ixPos = ixPos - XMOV;
        RtArea.left = iyPos - XMOV;
        if (ixPos < 0)
        {
          ixPos = 0;
          RtArea.left = 0;
        }
        myBitmap = leftBitmap;
        break;

      case VK_RIGHT:
        ixPos = ixPos + XMOV;
        if (ixPos > ixPos_Max - XTILE)
        {
          ixPos = ixPos_Max - XTILE;
        }
        myBitmap = rightBitmap;

        RtArea.right = +XMOV;
        break;

      case VK_UP:
        iyPos = iyPos - YMOV;
        if (iyPos < 0)
        {
          iyPos = 0;
        }
        myBitmap = rearBitmap;
        break;

      case VK_DOWN:
        iyPos = iyPos + YMOV;
        if (iyPos > iyPos_Max - YTILE)
        {
          iyPos = iyPos_Max - YTILE;
        }
        myBitmap = frontBitmap;
        break;
      }
      InvalidateRect(hWnd, &RtArea, TRUE);
      return 0;
  }
  return(DefWindowProc(hWnd, iMessage, wParam, lParam));
}



728x90