제대로 똥줄타는 숙제였다.
문제는 SJF알고리즘을 사용해서 프로세스 스케줄링 하는거다.
결론부터 말하자면 정답을 못구했다.
왜냐면 나 스스로 SJF알고리즘을 제대로 이해하지 못했다 ㅠㅠ

왠만한 학생들은 정말 제대로 똥줄탈 것이다.
제대로 똥줄타는 숙제이므로 소스는 공개하지 않겠다.

고려대 컴퓨터정보학과 학생중 진짜 진정으로 진심으로 똥줄이 팍팍 탄다면!!!
과기대에서 저를 만난다면!!! 커피한잔 사주세용^^ (꽁짜는 없씀)


사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지
Posted by 정훈승
사용자 삽입 이미지

#include <windows.h> // Windows API 함수를 위한 헤더파일
#include <tlhelp32.h> // 프로세스정보를 읽기 위한 헤더파일
#include <psapi.h> // enumprocess를 위한 헤더파일
#include <conio.h> // kbhit(아무키나 누르면 종료)를 위한 헤더파일
#include <ctime> // 시간출력을 위한 헤더파일
#include <iostream>
using namespace std;
static int signal; // abnormal인지 normal인지 구분, 매 삽입시마다 초기화되어야 하므로 static으로 선언
int count=0, cputime=0, pid;
SYSTEMTIME pkTimeProcess[1024]; // 이전 kernel time을 위한 배열
SYSTEMTIME puTimeProcess[1024]; // 이전 user time을 위한 배열
SYSTEMTIME ckTimeProcess[1024]; // 현재 kernel time을 위한 배열
SYSTEMTIME cuTimeProcess[1024]; // 현재 user time을 위한 배열
int previousCPU(DWORD processID, int i); // 이전 cpu정보를 얻음
int currentCPU(DWORD processID, int i); // 현재 cpu정보를 얻음
void tmPROCESS(DWORD processID); // 프로세스를 죽이는 함수
int kill(DWORD processID, int i); // 죽이는 조건
void main( )
{
 while(!_kbhit())
 {
  time_t lc;
  time(&lc);
  struct tm *today; // 시간 구조체 선언
  DWORD aProcesses[1024], cbNeeded, cProcesses; // 프로세스 리스트를 위한 변수
  unsigned int i;
  if (!EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded)) return; // EnumProcesses가 아니면 리턴
 
  cProcesses = cbNeeded / sizeof(DWORD); // 프로세스 리스트 저장
 
  for (i=0; i<cProcesses; i++) previousCPU(aProcesses[i], i);
  Sleep(1000); // 1000 = 1초
  for (i=0; i<cProcesses; i++) currentCPU(aProcesses[i], i);
  for (i=0; i<cProcesses; i++) kill(aProcesses[i], i);
  cout << localtime(&lc)->tm_year+1900 << "."; // 1900을 더해야 서기년도가 됨
  cout << localtime(&lc)->tm_mon+1 << "."; // 1월이 0이기 때문에 +1을 해야 됨
  cout << localtime(&lc)->tm_mday << " " << localtime(&lc)->tm_hour << ":" << localtime(&lc)->tm_min << ":" << localtime(&lc)->tm_sec;
  cout << ", " << "Current Process : " << i;
  if(signal == 0) cout << " - Normal\n";
  else cout << " - Abnormal\n"; // signal이 0이면 노말, 아니면 앱노말
 }
}
int previousCPU(DWORD processID, int i)
{
 FILETIME createTime1;
 FILETIME exitTime1;
 FILETIME kernelTimeProcess1;
 FILETIME userTimeProcess1;
 HANDLE hProcess;
 hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processID ); // 핸들 오픈
 if (NULL == hProcess) return 0; // 핸들이 프로세스를 갖고 있지 않다면 리턴
       
 GetProcessTimes( hProcess , &createTime1, &exitTime1, &kernelTimeProcess1, &userTimeProcess1); // cputime 계산
 FileTimeToSystemTime(&kernelTimeProcess1, &pkTimeProcess[i]); // system time 저장
 FileTimeToSystemTime(&userTimeProcess1, &puTimeProcess[i]); // system time 저장
}
int currentCPU(DWORD processID, int i)
{
 FILETIME createTime2;
 FILETIME exitTime2;
 FILETIME kernelTimeProcess2;
 FILETIME userTimeProcess2;
 HANDLE hProcess;
 hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processID ); // 핸들 오픈
 if (NULL == hProcess) return 0; // 핸들이 프로세스를 갖고 있지 않다면 리턴
       
 GetProcessTimes( hProcess , &createTime2, &exitTime2, &kernelTimeProcess2, &userTimeProcess2); // cputime 계산
 FileTimeToSystemTime(&kernelTimeProcess2, &ckTimeProcess[i]); // system time 저장
 FileTimeToSystemTime(&userTimeProcess2, &cuTimeProcess[i]); // system time 저장
}
void tmPROCESS(DWORD processID)
{
 HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processID );
 TerminateProcess(hProcess, NULL); // 과부하 프로세스 죽이는 함수
}
int kill(DWORD processID, int i)
{
 TCHAR szProcessName[MAX_PATH] = TEXT(""); // 파일경로 초기화
 HMODULE hMod; // 모듈정보를 얻기 위한 선언
 DWORD cbNeeded; // 모듈정보를 얻기 위한 선언
 HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processID ); // 핸들 오픈
 PROCESS_MEMORY_COUNTERS pmc; // 메모리저장을 위한 선언
 int cputime=0;
 if (NULL == hProcess) return 0; // 핸들이 프로세스를 갖고 있지 않다면 리턴
       
 if (EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbNeeded))
 GetModuleFileNameEx(hProcess, hMod, szProcessName, sizeof(szProcessName)/sizeof(TCHAR));
 cputime = // cpu사용률 계산
    (((((ckTimeProcess[i].wSecond*1000+ckTimeProcess[i].wMilliseconds)
   - (pkTimeProcess[i].wSecond*1000+pkTimeProcess[i].wMilliseconds))
   + (cuTimeProcess[i].wSecond*1000+cuTimeProcess[i].wMilliseconds )
   - (puTimeProcess[i].wSecond*1000+puTimeProcess[i].wMilliseconds)) /1000)*100);
 GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc)); // 메모리 정보를 얻음
 if((pmc.WorkingSetSize/(1024) + pmc.PagefileUsage/(1024)) >= 200000) // 메모리 과부하 종료조건
 {
  tmPROCESS(processID);
  cout << "Memory overloaded process is terminated.\n";
  cout << "PID : " << processID << " CPU : " << cputime;
  cout << " MEMORY : " << (pmc.WorkingSetSize/(1024) + pmc.PagefileUsage/(1024)) << "\n";
  _tprintf(TEXT("%s \n"), szProcessName); // 현재 파일경로
  signal = 1; // 0이 아니기 때문에 앱노말
 }
 else if(cputime >= 90) // cpu사용률 과부하 종료조건
 {
  tmPROCESS(processID);
  cout << "CPU overloaded process is terminated.\n";
  cout << "PID : " << processID << " CPU : " << cputime;
  cout << " MEMORY : " << (pmc.WorkingSetSize/(1024) + pmc.PagefileUsage/(1024)) << "\n";
  _tprintf(TEXT("%s \n"), szProcessName); // 현재 파일경로
  signal = 1; // 0이 아니기 때문에 앱노말
 }
 CloseHandle(hProcess); // 핸들 종료
}

매 초마다 cpu사용률과 메모리가 과부하 되는지 체크하는 프로그램입니다.
cpu사용률 또는 메모리가 과부하 되면 자동으로 그 프로세스를 죽여버립니다.

교수님께서 이 숙제를 내주시면서 말씀하셨습니다.
"하루 이틀 밤새는 걸로는 안될꺼에요"

그렇습니다. 이번 프로그래밍을 어디 참조 안하고 하루안에 푼다면 진짜 고수겠죠..
하지만 저를 비롯해서, 수많은 학생들이 고수가 아니기에...ㅠㅠ

깔끔하게 정리된 이 소스를 보고
어두운 감옥에서 한줄기 희망의 빛을 보시길 바랍니다 -_- ㅎㅎㅎㅎ


그리고 제 블로그 어딘가에 프로그래밍 숙제 도와드린단 말이 있나요?
있다면 그건,
고려대 과학기술대학 학생에 한하는 말입니다...
다른학교 숙제까지 해줄 정도로 제가 시간이 많지가 않아요 ㅠㅠ

고려대 과학기술대학 학생이 프로그래밍 숙제하다가 졸라 후달릴 경우
저에게 이메일 주시면 제가 도움을 줄 수도 있습니다. 
Posted by 정훈승
사용자 삽입 이미지

 
// Program Name : PROCESS COUNTER
// Written by Hoon-seung Jeong

// Consultation http://support.microsoft.com/kb/175030/ko


#include <iostream>
#include <windows.h>
// For Windows API function
#include <time.h>
// For time of day
#include <tlhelp32.h>
// For process count of Windows XP
using namespace std;
void Process_Count();
int main()
{
    while(1)
    {
        Process_Count();
    }
    return 0;
}
void Process_Count()
{
    int number=0;
// Initialization 0
    time_t now;
// Declare time struct
    now = time(NULL); // Time function
    HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); // This function has system information
    if(snap) // Excution snapshat handle
    {
        BOOL p_Count;
// For count process
        PROCESSENTRY32 p_Entry; // Declare process struct
        p_Entry.dwSize = sizeof(PROCESSENTRY32); // A Function of PROCESSENTRY32
        p_Count = Process32First(snap, &p_Entry); // Search a executing process
        while(p_Count)
        {
            p_Count = Process32Next(snap, &p_Entry);
// Repeat to search executing process
            number++;
// Increase number of executing process
        }
        CloseHandle(snap); // Close snapshot handle
    }
    cout << asctime(localtime(&now)); // Print time of day
    cout << "\tNumber of executing process : " << number << "\n"; // Print number of executing process
    Sleep(1000);
// 1000 is 1 second
}

프로그램 제목 : Process Counter

윈도우상에서 컨트롤+알트+델 누르면
윈도우즈 작업관리자가 뜨는데
왼쪽 하단에 현재 실행중인 프로세스 개수가 뜬다.

그걸 콘솔모드(도스모드) 프로그램으로 해본 것...
Posted by 정훈승
KOREA University/C++2009. 1. 12. 16:08

블록 생성하고
점수 계산하고
밑으로 떨어지면 죽고...
바는 마우스클릭된 상태에 움직인다.

문제는 존나 깜빡인다는 것,
더블버퍼링을 책보고 존나 해도 왜 난 잘 안될까...ㅠㅠ

문제가 다음버전에서 해결되길 바라며



Posted by 정훈승
KOREA University/C++2009. 1. 8. 22:28
사용자 삽입 이미지


API로 만든 간단한 예제게임
저 귀여운(?) 얼굴을 클릭하면 카운트가 올라간다.
제한시간은 10초
Posted by 정훈승
KOREA University/C++2009. 1. 3. 16:47
SimplePaint2 와 SimplePaint3 로 알려진 그 문제!!! (한빛미디어 교재)




네이버나 다음이나 구글이나 똑바로 된 소스가 없냐...
이거 푸는데 좀 고생고생했다.
이건 소스공개를 하지 않겠다.
나중에 해피캠퍼스에 올려야지 ㅡㅡ;;;

사용자 삽입 이미지
Posted by 정훈승
KOREA University/C++2009. 1. 1. 19:08
#include <windows.h>
#include "resource.h"
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
HINSTANCE g_hInst;
HWND hWndMain;
LPCTSTR lpszClass=TEXT("정훈승 SimplePaint");
enum {ID_R1=101, ID_R2, ID_R3, ID_R4, ID_R5, ID_R6, ID_R7, ID_R8, ID_R9 }; // 색상정보 정의
enum {ID_S1=201, ID_S2, ID_S3, ID_S4, ID_S5 }; // 선굵기정보 정의
HWND r1, r2, r3, r4, r5, r6, r7, r8, r9, s1, s2, s3, s4, s5;
// 핸들값
int Graph=0;
int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpszCmdParam,int nCmdShow)
{
 HWND hWnd;
 MSG Message;
 WNDCLASS WndClass;
 g_hInst=hInstance;
 HACCEL hAccel;
// 엑셀러레이터를 위해
 
 WndClass.cbClsExtra=0;
 WndClass.cbWndExtra=0;
 WndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
 //WndClass.hbrBackground=(HBRUSH)(COLOR_BTNFACE+1);;
 WndClass.hCursor=LoadCursor(NULL,IDC_ARROW);
 WndClass.hIcon=LoadIcon(NULL, IDI_APPLICATION);
 WndClass.hInstance=hInstance;
 WndClass.lpfnWndProc=WndProc;
 WndClass.lpszClassName=lpszClass;
 WndClass.lpszMenuName=MAKEINTRESOURCE(IDR_MENU1); // 메뉴 추가
 WndClass.style=CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
 RegisterClass(&WndClass);
 hWnd=CreateWindow(lpszClass,lpszClass,WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT, NULL,(HMENU)NULL,hInstance,NULL);
 ShowWindow(hWnd,nCmdShow);
 hAccel=LoadAccelerators(hInstance, MAKEINTRESOURCE(IDR_ACCELERATOR1)); // 엑셀러레이터를 위해
 
 while (GetMessage(&Message,NULL,0,0)) {
  if(!TranslateAccelerator(hWnd, hAccel, &Message)) { //
엑셀러레이터를 위해
   TranslateMessage(&Message);
   DispatchMessage(&Message);
  }
 }
 return (int)Message.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
 HDC hdc;
 PAINTSTRUCT ps;
 static int sx, sy, oldx, oldy;
// 마우스 현재 위치와 브러쉬 중첩을 위해
 static int jhs;
// case문을 효율적으로 활용하기 위해
 HPEN MyPen, OldPen;
// 펜을 위해
 static COLORREF Color=RGB(0,0,0); // 색상초기값 검정
 static Size=1;
// 선굵기 초기값 1
 static BOOL bNowDraw=FALSE; // 처음엔 선이 안그어지게 설정(마우스를 클릭해야 그어짐)
 
 switch (iMessage) {
 case WM_CREATE:
  CreateWindow(TEXT("button"), TEXT("Color▼"), WS_CHILD|WS_VISIBLE|BS_GROUPBOX,
   5, 5, 110, 300, hWnd, (HMENU)0, g_hInst, NULL);
  r1=CreateWindow(TEXT("button"), TEXT("검정색"), WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON|WS_GROUP,
   10, 20, 100, 30, hWnd, (HMENU)ID_R1, g_hInst, NULL);
  r2=CreateWindow(TEXT("button"), TEXT("빨강색"), WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON,
   10, 50, 100, 30, hWnd, (HMENU)ID_R2, g_hInst, NULL);
  r3=CreateWindow(TEXT("button"), TEXT("파랑색"), WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON,
   10, 80, 100, 30, hWnd, (HMENU)ID_R3, g_hInst, NULL);
  r4=CreateWindow(TEXT("button"), TEXT("초록색"), WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON,
   10, 110, 100, 30, hWnd, (HMENU)ID_R4, g_hInst, NULL);
  r5=CreateWindow(TEXT("button"), TEXT("보라색"), WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON,
   10, 140, 100, 30, hWnd, (HMENU)ID_R5, g_hInst, NULL);
  r6=CreateWindow(TEXT("button"), TEXT("크림슨색"), WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON,
   10, 170, 100, 30, hWnd, (HMENU)ID_R6, g_hInst, NULL);
  r7=CreateWindow(TEXT("button"), TEXT("오렌지색"), WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON,
   10, 200, 100, 30, hWnd, (HMENU)ID_R7, g_hInst, NULL);
  r8=CreateWindow(TEXT("button"), TEXT("분홍색"), WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON,
   10, 230, 100, 30, hWnd, (HMENU)ID_R8, g_hInst, NULL);
  r9=CreateWindow(TEXT("button"), TEXT("황금색"), WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON,
   10, 260, 100, 30, hWnd, (HMENU)ID_R9, g_hInst, NULL);
  CreateWindow(TEXT("button"), TEXT("Size▼"), WS_CHILD|WS_VISIBLE|BS_GROUPBOX,
   130, 5, 110, 180, hWnd, (HMENU)0, g_hInst, NULL);
  s1=CreateWindow(TEXT("button"), TEXT("선굵기1"), WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON|WS_GROUP,
   135, 20, 100, 30, hWnd, (HMENU)ID_S1, g_hInst, NULL);
  s2=CreateWindow(TEXT("button"), TEXT("선굵기2"), WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON,
   135, 50, 100, 30, hWnd, (HMENU)ID_S2, g_hInst, NULL);
  s3=CreateWindow(TEXT("button"), TEXT("선굵기3"), WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON,
   135, 80, 100, 30, hWnd, (HMENU)ID_S3, g_hInst, NULL);
  s4=CreateWindow(TEXT("button"), TEXT("선굵기4"), WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON,
   135, 110, 100, 30, hWnd, (HMENU)ID_S4, g_hInst, NULL);
  s5=CreateWindow(TEXT("button"), TEXT("선굵기5"), WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON,
   135, 140, 100, 30, hWnd, (HMENU)ID_S5, g_hInst, NULL);
  CheckRadioButton(hWnd,ID_R1,ID_R9,ID_R1);
  CheckRadioButton(hWnd,ID_S1,ID_S5,ID_S1);
  break;
 case WM_COMMAND:
  switch(LOWORD(wParam)) {
  case ID_R1: Color=RGB(0, 0, 0); break; // 검정색
  case ID_R2: Color=RGB(255, 0, 0); break; // 빨강색
  case ID_R3: Color=RGB(0, 0, 255); break;
// 파랑색
  case ID_R4: Color=RGB(0, 140, 0); break;
// 초록색
  case ID_R5: Color=RGB(130, 0, 130); break;
// 보라색
  case ID_R6: Color=RGB(129, 0, 45); break; // 크림슨색
  case ID_R7: Color=RGB(255, 138, 0); break;
// 오렌지색
  case ID_R8: Color=RGB(255, 100, 255); break; // 분홍색
  case ID_R9: Color=RGB(255, 174, 0); break;
// 황금색
 
  case ID_S1: Size=1; break;
  case ID_S2: Size=2; break;
  case ID_S3: Size=3; break;
  case ID_S4: Size=4; break;
  case ID_S5: Size=5; break;
  case IDM_FILE_MENU1:
   jhs = 1; // case문을 효율적으로 활용하기 위해 임의 숫자를 입력
   MessageBox(hWnd, TEXT("자유곡선을 선택했습니다."), TEXT("정훈승 SimplePaint"), MB_OK);
   return 0;
  case IDM_FILE_MENU2:
   jhs = 2;
   MessageBox(hWnd, TEXT("직선을 선택했습니다."), TEXT("정훈승 SimplePaint"), MB_OK);
   return 0;
  case IDM_FILE_MENU3:
   jhs = 3;
   MessageBox(hWnd, TEXT("원을 선택했습니다."), TEXT("정훈승 SimplePaint"), MB_OK);
   return 0;
  case IDM_FILE_MENU4:
   jhs = 4;
   MessageBox(hWnd, TEXT("사각형을 선택했습니다."), TEXT("정훈승 SimplePaint"), MB_OK);
   return 0;
  case IDM_FILE_MENU5:
   MessageBox(hWnd, TEXT("화면을 초기화합니다."), TEXT("정훈승 SimplePaint"), MB_OK);
   InvalidateRect(hWnd,NULL,TRUE);
   return 0;
  case IDM_FILE_EXIT:
   DestroyWindow(hWnd);
   break;
  case IDM_COLOR1:
   MessageBox(hWnd, TEXT("Black 선택"), TEXT("정훈승 SimplePaint"), MB_OK);
   Color=RGB(0, 0, 0); return 0;
  case IDM_COLOR2:
   MessageBox(hWnd, TEXT("Red 선택"), TEXT("정훈승 SimplePaint"), MB_OK);
   Color=RGB(255, 0, 0); return 0;
  case IDM_COLOR3:
   MessageBox(hWnd, TEXT("Blue 선택"), TEXT("정훈승 SimplePaint"), MB_OK);
   Color=RGB(0, 0, 255); return 0;  
  case IDM_COLOR4:
   MessageBox(hWnd, TEXT("Green 선택"), TEXT("정훈승 SimplePaint"), MB_OK);
   Color=RGB(0, 140, 0); return 0;  
  case IDM_COLOR5:
   MessageBox(hWnd, TEXT("Violet 선택"), TEXT("정훈승 SimplePaint"), MB_OK);
   Color=RGB(130, 0, 130); return 0;  
  case IDM_COLOR6:
   MessageBox(hWnd, TEXT("Crimson 선택"), TEXT("정훈승 SimplePaint"), MB_OK);
   Color=RGB(129, 0, 45); return 0;
  case IDM_COLOR7:
   MessageBox(hWnd, TEXT("Orange 선택"), TEXT("정훈승 SimplePaint"), MB_OK);
   Color=RGB(255, 138, 0); return 0;
  case IDM_COLOR8:
   MessageBox(hWnd, TEXT("Pink 선택"), TEXT("정훈승 SimplePaint"), MB_OK);
   Color=RGB(255, 100, 255); return 0;
  case IDM_COLOR9:
   MessageBox(hWnd, TEXT("Gold 선택"), TEXT("정훈승 SimplePaint"), MB_OK);
   Color=RGB(255, 174, 0); return 0;
  case IDM_SIZE1: MessageBox(hWnd, TEXT("매우 얇게 선택"), TEXT("정훈승 SimplePaint"), MB_OK); Size=1; return 0;
  case IDM_SIZE2: MessageBox(hWnd, TEXT("얇게  선택"), TEXT("정훈승 SimplePaint"), MB_OK); Size=2; return 0;
  case IDM_SIZE3: MessageBox(hWnd, TEXT("보통 선택"), TEXT("정훈승 SimplePaint"), MB_OK); Size=3; return 0;
  case IDM_SIZE4: MessageBox(hWnd, TEXT("굵게 선택"), TEXT("정훈승 SimplePaint"), MB_OK); Size=4; return 0;
  case IDM_SIZE5: MessageBox(hWnd, TEXT("매우 굵게 선택"), TEXT("정훈승 SimplePaint"), MB_OK); Size=5; return 0;
  }
  return 0;
 case WM_LBUTTONDOWN:
  sx = LOWORD(lParam); // 마우스 현재 위치
  sy = HIWORD(lParam);
  oldx = sx;
// 브러쉬 중첩
  oldy = sy;
  bNowDraw = TRUE;
  return 0;
 case WM_MOUSEMOVE:
  if(bNowDraw) {
   hdc = GetDC(hWnd);
   switch(jhs) {
   case 1:
// 자유곡선
    MyPen=CreatePen(PS_SOLID, Size, Color);
    OldPen=(HPEN)SelectObject(hdc, MyPen);
    MoveToEx(hdc, sx, sy, NULL);
    sx=LOWORD(lParam);
    sy=HIWORD(lParam);
    LineTo(hdc, sx, sy);
    SelectObject(hdc, OldPen);
    DeleteObject(MyPen);
    ReleaseDC(hWnd, hdc);
    return 0;
   case 2:
// 선
    MyPen=CreatePen(PS_SOLID, Size, Color);
    OldPen=(HPEN)SelectObject(hdc, MyPen);
    SetROP2(hdc, R2_NOTXORPEN);
    MoveToEx(hdc, sx, sy, NULL);
    LineTo(hdc, oldx, oldy);
    oldx=LOWORD(lParam);
    oldy=HIWORD(lParam);
    MoveToEx(hdc, sx ,sy, NULL);
    LineTo(hdc, oldx, oldy);
    ReleaseDC(hWnd, hdc);
    return 0;
   case 3:
// 원
    MyPen=CreatePen(PS_SOLID, Size, Color);
    OldPen=(HPEN)SelectObject(hdc, MyPen);
    SetROP2(hdc, R2_NOTXORPEN);
    Ellipse(hdc, sx, sy, oldx, oldy);
    sx=LOWORD(lParam);
    sy=HIWORD(lParam);
    Ellipse(hdc, sx, sy, oldx, oldy);
    SelectObject(hdc, OldPen);
    DeleteObject(MyPen);
    ReleaseDC(hWnd, hdc);
    return 0;
   case 4:
// 사각형
    MyPen=CreatePen(PS_SOLID, Size, Color);
    OldPen=(HPEN)SelectObject(hdc, MyPen);
    SetROP2(hdc, R2_NOTXORPEN);
    Rectangle(hdc, sx, sy, oldx, oldy);
    sx=LOWORD(lParam);
    sy=HIWORD(lParam);
    Rectangle(hdc, sx, sy, oldx, oldy);
    SelectObject(hdc, OldPen);
    DeleteObject(MyPen);
    ReleaseDC(hWnd, hdc);
    return 0;
   }
   MyPen=CreatePen(PS_SOLID, Size, Color); // 초기값 자유곡선
   OldPen=(HPEN)SelectObject(hdc, MyPen);
   MoveToEx(hdc, sx, sy, NULL);
   sx=LOWORD(lParam);
   sy=HIWORD(lParam);
   LineTo(hdc, sx, sy);
   SelectObject(hdc, OldPen);
   DeleteObject(MyPen);
   ReleaseDC(hWnd, hdc);
  }
  return 0;
 
 case WM_LBUTTONUP:
  bNowDraw = FALSE; // 마우스를 땠을 때 선 안그어짐
  hdc = GetDC(hWnd);
  return 0;
 case WM_PAINT:
  hdc=BeginPaint(hWnd, &ps);
  TextOut(hdc, 1, 320, TEXT("ㆍ초기값 : 자유곡선, 매우 얇게"), 30);
  TextOut(hdc, 1, 345, TEXT("ㆍ자유곡선 선택 : Ctrl+I"), 24);
  TextOut(hdc, 1, 370, TEXT("ㆍ직선 선택 : Ctrl+L    "), 24);
  TextOut(hdc, 1, 395, TEXT("ㆍ원 선택 : Ctrl+E      "), 24);
  TextOut(hdc, 1, 420, TEXT("ㆍ사각형 선택 : Ctrl+R  "), 24);
  TextOut(hdc, 1, 445, TEXT("ㆍ화면 초기화 : Ctrl+S  "), 24);
  TextOut(hdc, 1, 470, TEXT("ㆍ프로그램 종료 : Ctrl+X"), 24);
  EndPaint(hWnd, &ps);
  return 0;
 case WM_DESTROY:
  PostQuitMessage(0);
  return 0;
 }
 return(DefWindowProc(hWnd,iMessage,wParam,lParam));
}

SimplePaint 문제로 유명한 그 소스의 해답이라고 말하고 싶다.


첨보는 사람은 그냥 존나 긴~ 쏘스라고만 생각하겠지만
차근차근 공부하면 뭔말인지 다 이해가 감
리소스 추가는 셀프^^
Posted by 정훈승
KOREA University/C++2008. 12. 28. 17:01
#include <windows.h>
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
HINSTANCE g_hInst;
LPCTSTR lpszClass=TEXT("정훈승 자유주제3");
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;
 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, NULL, 0, 0)) {
  TranslateMessage(&Message);
  DispatchMessage(&Message);
 }
 return (int)Message.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
 HDC hdc;
 PAINTSTRUCT ps;
 int i, j;
 static int sx, sy;
 switch(iMessage) {
 case WM_PAINT:
  hdc=BeginPaint(hWnd, &ps);
  for(i=0; i<768; i=i+17)
  {
   MoveToEx(hdc,0,i,NULL);
   LineTo(hdc,1024,i);
  }
  for(j=0; j<1024; j=j+17)
  {
   MoveToEx(hdc,j,0,NULL);
   LineTo(hdc,j,768);
  }
  EndPaint(hWnd, &ps);
  return 0;
 case WM_LBUTTONDOWN:
  hdc=GetDC(hWnd);
  sx=LOWORD(lParam);
  sy=HIWORD(lParam);
  TextOut(hdc, sx, sy, TEXT("●"), 2);
  ReleaseDC(hWnd, hdc);
  return 0;
 case WM_RBUTTONDOWN:
  hdc=GetDC(hWnd);
  sx=LOWORD(lParam);
  sy=HIWORD(lParam);
  TextOut(hdc, sx, sy, TEXT("○"), 2);
  ReleaseDC(hWnd, hdc);
  return 0;
 
 case WM_DESTROY:
  PostQuitMessage(0);
  return 0;
 }
 return(DefWindowProc(hWnd, iMessage, wParam, lParam));
}

이 소스는 아주 간단한 소스다.
내가 짰으면서도 너무 아이디어가 기발-_-해서 공유한다.

윈도우즈프로그래밍(API) 초반부 단계 숙제용으로 탁월한 예가 될 것이다.

화면에 바둑판을 그려놓고
왼쪽버튼 누르면 검정색돌, 오른쪽버튼 누르면 흰색돌

아주 기초적인 지식으로 이따구 것을 만들어서 숙제 제출하면
아마 담당 교수님이나 담당 강의선생생님께 칭찬을 들을것이라 예상된다.
Posted by 정훈승
KOREA University/C++2008. 12. 28. 16:56
#include <windows.h>
#include "resource.h"
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
HINSTANCE g_hInst;
HWND hWndMain;
LPCTSTR lpszClass=TEXT("정훈승 RopMode2");
int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpszCmdParam,int nCmdShow)
{
 HWND hWnd;
 MSG Message;
 WNDCLASS WndClass;
 g_hInst=hInstance;
 HACCEL hAccel; // 엑셀러레이터를 위해
 
 WndClass.cbClsExtra=0;
 WndClass.cbWndExtra=0;
 WndClass.hbrBackground=(HBRUSH)(COLOR_WINDOW+1);
 WndClass.hCursor=LoadCursor(NULL,IDC_ARROW);
 WndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
 WndClass.hInstance=hInstance;
 WndClass.lpfnWndProc=WndProc;
 WndClass.lpszClassName=lpszClass;
 WndClass.lpszMenuName=MAKEINTRESOURCE(IDR_MENU1); // 메뉴 추가
 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);
 hAccel=LoadAccelerators(hInstance, MAKEINTRESOURCE(IDR_ACCELERATOR1)); // 엑셀러레이터를 위해
 
 while (GetMessage(&Message,NULL,0,0)) {
  if(!TranslateAccelerator(hWnd, hAccel, &Message)) { // 엑셀러레이터를 위해
   TranslateMessage(&Message);
   DispatchMessage(&Message);
  }
 }
 return (int)Message.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
 static int sx, sy, oldx, oldy; // 마우스 현재 위치와 브러쉬 중첩을 위해
 static BOOL bNowDraw = FALSE;
 HDC hdc;
 static int jhs; // case문을 효율적으로 활용하기 위해
 HBRUSH MyBrush, OldBrush; // 브러쉬를 위해
 switch (iMessage) {
 case WM_COMMAND:
  switch(LOWORD(wParam)) {
  case IDM_FILE_MENU1:
   jhs = 1; // case문을 효율적으로 활용하기 위해 임의 숫자를 입력
   MessageBox(hWnd, TEXT("자유곡선을 선택했습니다."), TEXT("정훈승 RopMode2"), MB_OK);
   return 0;
  case IDM_FILE_MENU2:
   jhs = 2;
   MessageBox(hWnd, TEXT("선을 선택했습니다."), TEXT("정훈승 RopMode2"), MB_OK);
   return 0;
  case IDM_FILE_MENU3:
   jhs = 3;
   MessageBox(hWnd, TEXT("원을 선택했습니다."), TEXT("정훈승 RopMode2"), MB_OK);
   return 0;
  case IDM_FILE_MENU4:
   jhs = 4;
   MessageBox(hWnd, TEXT("사각형을 선택했습니다."), TEXT("정훈승 RopMode2"), MB_OK);
   return 0;
  case IDM_FILE_EXIT:
   DestroyWindow(hWnd);
   break;
  }
 case WM_LBUTTONDOWN:
  sx = LOWORD(lParam); // 마우스 현재 위치
  sy = HIWORD(lParam);
  oldx = sx; // 브러쉬 중첩
  oldy = sy;
  bNowDraw = TRUE;
  return 0;
 case WM_MOUSEMOVE:
  if(bNowDraw) {
   hdc = GetDC(hWnd);
   switch(jhs) {
   case 1: // 자유곡선
    MoveToEx(hdc, sx, sy, NULL);
    sx = LOWORD(lParam);
    sy = HIWORD(lParam);
    LineTo(hdc, sx, sy);
    ReleaseDC(hWnd, hdc);
    return 0;
   case 2: // 선
    SetROP2(hdc, R2_NOT);
    MoveToEx(hdc, sx, sy, NULL);
    LineTo(hdc, oldx, oldy);
    oldx=LOWORD(lParam);
    oldy=HIWORD(lParam);
    MoveToEx(hdc, sx ,sy, NULL);
    LineTo(hdc, oldx, oldy);
    ReleaseDC(hWnd, hdc);
    return 0;
   case 3: // 원
    MyBrush = CreateSolidBrush(RGB(0,0,0));
    OldBrush = (HBRUSH)SelectObject(hdc, MyBrush);
    SetROP2(hdc, R2_NOT);
    SelectObject(hdc,GetStockObject(NULL_BRUSH));
    Ellipse(hdc, sx, sy, oldx, oldy);
    oldx=LOWORD(lParam);
    oldy=HIWORD(lParam);
    Ellipse(hdc, sx, sy, oldx, oldy);
    DeleteObject(SelectObject(hdc, OldBrush));
    ReleaseDC(hWnd, hdc);
    return 0;
   case 4: // 사각형
    MyBrush = CreateSolidBrush(RGB(0,0,0));
    OldBrush = (HBRUSH)SelectObject(hdc,MyBrush);
    SetROP2(hdc, R2_NOT);
    SelectObject(hdc,GetStockObject(NULL_BRUSH));
    Rectangle(hdc, sx, sy, oldx, oldy);
    oldx=LOWORD(lParam);
    oldy=HIWORD(lParam);
    Rectangle(hdc, sx, sy, oldx, oldy);
    DeleteObject(SelectObject(hdc, OldBrush));
    ReleaseDC(hWnd, hdc);
    return 0;
   }
   return 0;
  }
 case WM_LBUTTONUP:
  bNowDraw = FALSE; // 마우스를 땠을 때 선 안그어짐
  hdc = GetDC(hWnd);
  return 0;
 case WM_DESTROY:
  PostQuitMessage(0);
  return 0;
 }
 return(DefWindowProc(hWnd,iMessage,wParam,lParam));
}


RopMode2 로 자~알 알려진 그 문제다.

메뉴에서 해당 그리기모드로 선택하면 그 그리기모드가 된다.

1. 자유곡선
2. 그냥 선
3. 원
4. 사각형

이렇게 4가지 모드를 지원하고, 각 모드는 단축키가 있다.

네이버에 이거 구라쏘스 존나 많던데,
내 쏘스 본사람은 행운아

※ 내 소스가 드래그가 안되서 Ctrl+C, Ctrl+V 신공이 안먹혀서 욕을 할 수도 있겠지만,
나는 프로그래밍 소스는 직접 쳐봐야 한다는 신념을 가지고 있다.
한번쯤 직접 쳐보고, 오타 수정하면서 해야 실력이 일취월장 할 것이다.
Posted by 정훈승
KOREA University/C++2008. 12. 28. 16:51
#include <windows.h>
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
HINSTANCE g_hInst;
LPCTSTR lpszClass=TEXT("keydown2");
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;
 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, NULL, 0, 0)) {
  TranslateMessage(&Message);
  DispatchMessage(&Message);
 }
 return (int)Message.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
 HDC hdc;
 PAINTSTRUCT ps;
 static int x=100;
 static int y=100;
 static TCHAR str[256]={'A'};
 
 switch(iMessage) {
 case WM_KEYDOWN:
  switch(wParam) {
  case VK_LEFT: x-=8; break;
  case VK_RIGHT: x+=8; break;
  case VK_UP:  y-=8; break;
  case VK_DOWN: y+=8; break;
  case VK_SPACE: // 여기부터
   if(str[0]=='A')
   {
    str[0]='#';
   }
   else
   {
    str[0]='A';
   } // 여기까지가 키포인트
  }
  InvalidateRect(hWnd,NULL,TRUE);
  return 0;
 case WM_PAINT:
  hdc=BeginPaint(hWnd,&ps);
  TextOut(hdc,x,y,str,lstrlen(str));
  EndPaint(hWnd,&ps);
  return 0;
 case WM_DESTROY:
  PostQuitMessage(0);
  return 0;
 }
 return(DefWindowProc(hWnd, iMessage, wParam, lParam));
}

KeyDown2 문제로 유명한 그 문제

스페이스 누르면 A에서 #으로 바뀐다. 그리고 다시 스페이스 누르면 #에서 A로 다시...

2년전에 MFC를 존나 공부한적이 있었는데, 그때 쫌 해놨더니
API공부하고 있는 요즘, 존나 수월하게 진도가 나가고 있다.
Posted by 정훈승