황동준님의 윈도우 32비트 프로그래밍 41~45

  윈도우 32비트 프로그래밍 36

안녕하세요…………….돌팔이
황동준입니다…………………

오늘은 또 다른 방법으로 파일 입출력을 해보도록 하겠습니다. 이 방법은 앞에서 알아 본
방법보다는 약간 복잡하지만 꼭 알아 두셔야 합니다. 왜냐하면 이 방법으로 통신 포트를 제어할 수 있거든요. 원리는 앞 부분하고 크게 다른 점은
없습니다.

자 그러면 어떤 식으로 하는지 구체적으로 알아 봅시다. 먼저 약간 다른 점이 하나 있습니다.
위에서 한 방법대로라면은 파일에 정보를 기록할 때 먼저 파일을 생성하고 그 다음에 그 파일을 열었는데 이번 방법으로는 그 과정을 하나의 함수로
할 수 있습니다. 물론 그 함수의 파라미터에 파일을 생성하고 연다는 것을 지정하는 부분이 있습니다. 아래 함수를 이용해서 파일을 열고 생성하는
과정을 할 수 있습니다.

HANDLE CreateFile(
    LPCTSTR
 lpszName,
    DWORD  fdwAccess,
    DWORD
 fdwShareMode,
    LPSECURITY_ATTRIBUTES  lpsa,
    DWORD
 fdwCreate,
    DWORD  fdwAttrsAndFlags,
    HANDLE
 hTemplateFile
   );

우리가 앞에서 알아본 파일 입출력함수들은 HFILE이라는 자료형을 사용했던 것에 비해서
지금부터 알아 볼 파일 핸들은 HANDLE이라는 자료형을 사용한다는 것을 알 수 있습니다. 함수 리턴값을 보면 알겠죠? 자 그러면 각 파라미터에
어떤 값들을 지정하는지 알아 봅시다. 조금 복잡하죠?

첫번째 파라미터인 lpszName에는 생성하거나 열 파일이름을 지정하면 됩니다. 두번째
파라미터인 fdwAccess는 파일을 어떤식으로 열 것인지를 지정하면 됩니다. 우리가 앞에서 알아본 읽기 전용, 쓰기 전용 뭐 이런 것들을
의미하는 거죠. 이 파라미터에는 다음과 같은 예약어가 지정될 수 있습니다.

GENERIC_READ    읽기 전용으로 파일을 엽니다.
GENERIC_WRITE
  쓰기 전용으로 파일을 엽니다.

세번째 파라미터인 fdwShareMode는 파일을 공유할 것인지 지정하는 곳인데 이곳에
지정될 수 있는 예약어는 다음과 같습니다.

0                   파일을 공유하지
않습니다.
FILE_SHARE_READ     다른 파일에서 읽는 것을 허락합니다.
FILE_SHARE_WRITE    다른 파일에서
쓰기를 허락합니다.

네번째 파라미터인 lpsa에는 보통 NULL값을 지정합니다. 그리고 다섯번째 파라미터인
fdwCreate에는 파일에 대한 어떤 행동방식을 지정해 주는 것인데 이곳에 지정될 수 있는 예약어는 다음과 같습니다.

CREATE_NEW      파일을 생성합니다.
CREATE_ALWAYS   파일을
생성합니다.
OPEN_EXISTING   존재하는 파일을 엽니다.
OPEN_ALWAYS     파일을 엽니다.

파일을 생성하는 CREATE_NEW와 CREATE_ALWAYS의 차이점은 무엇일까요?
CREATE_NEW를 이용해서 파일을 생성할 때 만약에 같은 이름의 파일이 존재하면 새로 생성하지 않습니다. 그러나 CREATE_ALWAYS는
덮어쓴다는 차이점이 있죠.

여섯번째 파라미터인 fdwAttrsAndFlags는 파일의 속성을 지정하는 것인데 이곳에는
다음과 같은 예약어가 올 수 있습니다.

FILE_ATTRIBUTE_NORMAL       일반적인 파일을
의미합니다.
FILE_ATTRIBUTE_HIDDEN       히든 파일을 의미합니다.
FILE_ATTRIBUTE_READONLY
    읽기 전용 파일을 의미합니다.
FILE_ATTRIBUTE_SYSTEM       시스템 파일을 의미합니다.

마지막 파라미터인 hTemplateFile에는 보통 NULL을 지정하여 사용합니다.

자 파일을 생성하고 여는 기능을 가진 함수인 CreateFile()함수에 대해 알아 보았으니
다 사용한 후에 닫는 함수를 알아 봅시다.

BOOL CloseHandle(
    HANDLE  hObject
   );
  

파라미터로 파일을 열었을 때 얻은 파일의 핸들을 지정해 주면 됩니다.

자 이번에는 파일에서 정보를 읽고 쓰는 함수에 대해 알아 보죠. 파일에 정보를 기록할 때에는
다음의 함수를 사용합니다.

BOOL WriteFile(
    HANDLE
 hFile,
    LPCVOID  lpBuffer,
    DWORD
 nNumberOfBytesToWrite,
    LPDWORD
 lpNumberOfBytesWritten,
    LPOVERLAPPED  lpOverlapped
   );   

함수 이름에서도 쉽게 정보를 기록하는 역할을 한다는 것을 알 수 있죠? 각 파라미터가
의미하는 바를 알아 봅시다.

첫번째 파라미터에는 파일의 핸들을 지정해 주면 됩니다. 앞에서 알아본 CreateFile()
함수의 리턴값을 지정해 주면 됩니다. 두번째 파라미터인 lpBuffer는 정보를 저장하고 있는 버퍼의 주소를 의미합니다. 세번째 파라미터인
nNumberOfBytesToWrite는 버퍼의 크기를 의미하고 네번째 파라미터인 lpNumberOfBytesWritten은 실제로 기록된
정보의 크기값이 저장되는 변수의 주소입니다. 마지막 파라미터인 lpOverlapped에는 보통 NULL을 지정하면 됩니다.

이번에는 정보를 읽어올 수 있는 ReadFile() 함수에 대해 알아 보죠. 파라미터의
의미는 위 WriteFile() 함수와 같습니다.

BOOL ReadFile(
    HANDLE  hFile,
    LPVOID
 lpBuffer,
    DWORD  nNumberOfBytesToRead,
    LPDWORD
 lpNumberOfBytesRead,
    LPOVERLAPPED  lpOverlapped
   );   

자 그러면 우리가 앞에서 만들어 본 파일 입출력 예제 프로그램을 지금 배운 IO 함수를
이용해서 똑같이 구현해 보도록 합시다.

MyMenu MENU
BEGIN
    POPUP
“&File”
    BEGIN
        MENUITEM “&Save”,
100
        MENUITEM “&Load”, 200
    END
END

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

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM,
LPARAM);
void SaveProc(void);
void LoadProc(void);
char
GetHeader(void);
LPSTR GetData(void);

typedef struct tagMYFILE
{
    char
cHeader;
    char szData[80];
} MYFILE;

MYFILE MyFile;

int WINAPI WinMain
(HINSTANCE hInstance,
HINSTANCE hPrevInstance, LPSTR lpszArg, int nCmdShow)
{
        static
char szAppName[] = “File & Directory Example”;
        HWND
hWnd;
        MSG msg;
        WNDCLASS WndClass;

        WndClass.style =
CS_HREDRAW|CS_VREDRAW;
        WndClass.lpfnWndProc =
WndProc;
        WndClass.cbClsExtra = 0;
        WndClass.cbWndExtra =
0;
        WndClass.hInstance = hInstance;
        WndClass.hIcon =
LoadIcon(NULL, IDI_APPLICATION);
        WndClass.hCursor = LoadCursor(NULL,
IDC_ARROW);
        WndClass.hbrBackground =
GetStockObject(WHITE_BRUSH);
        WndClass.lpszMenuName =
“MyMenu”;
        WndClass.lpszClassName =
szAppName;
        if(!RegisterClass(&WndClass))
                return
FALSE;

        hWnd =
CreateWindow(
                szAppName,
                szAppName,
                WS_OVERLAPPEDWINDOW,
                CW_USEDEFAULT,
                CW_USEDEFAULT,
                CW_USEDEFAULT,
                CW_USEDEFAULT,
                NULL,
                NULL,
                hInstance,
                NULL
        );

        ShowWindow(hWnd,
nCmdShow);
        UpdateWindow(hWnd);

        while(GetMessage(&msg, NULL, 0,
0))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }

        return msg.wParam;
}

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

        static char cHeader;
        static char
szData[80];

        switch(message)
        {
            case
WM_CREATE :

                cHeader = '
';
                return 0;

            case WM_PAINT :

                hDC = BeginPaint(hWnd,
&ps);
                TextOut(hDC, 100, 100, &cHeader,
1);
                TextOut(hDC, 100, 150, szData,
strlen(szData));
                EndPaint(hWnd,
&ps);
                return 0;

            case WM_COMMAND :

                switch(LOWORD(wParam))
                {
                    case
100 :

                        SaveProc();
                        break;

                    case 200 :

                        LoadProc();
                        cHeader
= GetHeader();
                        strcpy(szData,
GetData());
                        InvalidateRect(hWnd, NULL,
FALSE);
                        break;
                }
                return
0;

            case WM_DESTROY :

                PostQuitMessage(0);
                return
0;
        }
        return DefWindowProc(hWnd, message, wParam,
lParam);
}

void SaveProc(void)
{
    HANDLE
hFile;
    MYFILE tmpMyFile;
    DWORD dwBuffer;

    tmpMyFile.cHeader =
'A';
    strcpy(tmpMyFile.szData, “This is File Data”);

    hFile = CreateFile(“e:test.txt”,
GENERIC_WRITE, 0, NULL, CREATE_NEW,
        FILE_ATTRIBUTE_NORMAL,
NULL);
    WriteFile(hFile, (char *)&tmpMyFile, sizeof(MYFILE),
&dwBuffer, NULL);
    CloseHandle(hFile);
}

void LoadProc(void)
{
    HANDLE
hFile;
    DWORD dwBuffer;

    hFile = CreateFile(“e:test.txt”,
GENERIC_READ, 0, NULL, OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
NULL);
    ReadFile(hFile, (MYFILE *)&MyFile, sizeof(MYFILE),
&dwBuffer, NULL);
    CloseHandle(hFile);
}

char GetHeader(void)
{
    return
MyFile.cHeader;
}

LPSTR GetData(void)
{
    return
MyFile.szData;
}

역시 마찬가지로 크게 네개의 함수가 보이죠? 각 함수를 보도록 합시다.

void SaveProc(void)
{

이 함수는 정보를 저장하는 역할을 합니다.

    HANDLE hFile;

앞에서 알아 본 HFILE이라는 자료형 대신에  HANDLE이라는 자료형을
사용합니다.

    MYFILE tmpMyFile;
    DWORD dwBuffer;

    tmpMyFile.cHeader =
'A';
    strcpy(tmpMyFile.szData, “This is File Data”);

    hFile = CreateFile(“e:test.txt”,
GENERIC_WRITE, 0, NULL, CREATE_NEW,
        FILE_ATTRIBUTE_NORMAL, NULL);

파일을 생성해서 그 파일을 쓰기 전용으로 열고 있는 구문입니다. 일반적인 파일의 속성을 가진
파일이 생성되고 열리겠군요.

    WriteFile(hFile, (char *)&tmpMyFile,
sizeof(MYFILE), &dwBuffer, NULL);
    CloseHandle(hFile);

파일에 정보를 기록하고 닫는 구문입니다.

}

void LoadProc(void)
{

이 함수는 파일에서 정보를 읽어오는 역할을 합니다.

    HANDLE hFile;
    DWORD dwBuffer;

    hFile = CreateFile(“e:test.txt”,
GENERIC_READ, 0, NULL, OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
NULL);

존재하는 파일을 읽기전용으로 열고 있는 구문입니다.

    ReadFile(hFile, (MYFILE *)&MyFile,
sizeof(MYFILE), &dwBuffer, NULL);
    CloseHandle(hFile);

파일에서 정보를 읽고 닫는 구문입니다.

}

char GetHeader(void)
{
    return
MyFile.cHeader;
}

LPSTR GetData(void)
{
    return
MyFile.szData;
}

읽어온 정보의 값을 되돌려 주고 있는 역할을 하는 것이 바로 위 두개의 함수입니다.

자 오늘은 여기까지
끝~~~~~~~~~~~~~~~~~~~~~~~~

 

  윈도우 32비트 프로그래밍 37

안녕하세요………..돌팔이 황동준입니다.

이번시간에는 파일을 복사하고 옮기고 지우는 작업을 프로그램상에서 어떻게 구현하는지 알아
보겠습니다. 각각 그 역할을 하는 함수가 있으니 사용방법만 알면 아주 간단하게 구현할 수 있죠. 함수 사용방법도 아주 간단합니다.

먼저 파일을 복사하는 함수를 보도록 합시다. 파일을 복사할때에는 CopyFile()이라는
함수를 사용합니다.

BOOL CopyFile(
    LPCTSTR
 lpszExistingFile,
    LPCTSTR  lpszNewFile,
    BOOL
 fFailIfExists
   );   

첫번째 파라미터에 복사할 파일이름을 지정하면 되고 두번째 파라미터에 복사될 파일이름을
지정하면 됩니다. 그러면 세번째 파라미터는 무엇을 의미할까요?

세번째 파라미터는 이미 파일이 존재할 때 어떻게 할 것인지 지정하는 것입니다. 만약에 이
값이 TRUE면 파일을 덮어쓰지 않고 FALSE면 덮어 씁니다.

자 이번에는 파일을 옮기는 역할을 하는 MoveFile()함수입니다.

BOOL MoveFile(
    LPCTSTR
 lpszExisting,
    LPCTSTR  lpszNew
   );

더 간단하죠? 첫번째 파라미터는 옮길 파일 이름을 지정하면 되고 두번째 파라미터에는
짐작하신대로 옮기고 난 후의 파일이름을 지정하면 됩니다.

마지막으로 파일을 지우는 함수인 DeleteFile() 함수입니다.

BOOL DeleteFile(
    LPCTSTR
 lpszFileName
   );

지울 파일이름을 파라미터로 지정해 주면 됩니다.

파일을 복사, 옮기고, 지우는 것이 상당히 쉽죠? 그러면 앞에서 만든 프로그램에 이 기능을
추가해 봅시다.

MyMenu MENU
BEGIN
    POPUP
“&File”
    BEGIN
        MENUITEM “&Save”,
100
        MENUITEM “&Load”, 200
        MENUITEM
SEPARATOR
        MENUITEM “&Copy”, 300
        MENUITEM “&Move”,
400
        MENUITEM “&Del”, 500
    END
END

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

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM,
LPARAM);
void SaveProc(void);
void LoadProc(void);
char
GetHeader(void);
LPSTR GetData(void);

typedef struct tagMYFILE
{
    char
cHeader;
    char szData[80];
} MYFILE;

MYFILE MyFile;

int WINAPI WinMain
(HINSTANCE hInstance,
HINSTANCE hPrevInstance, LPSTR lpszArg, int nCmdShow)
{
        static
char szAppName[] = “File & Directory Example”;
        HWND
hWnd;
        MSG msg;
        WNDCLASS WndClass;

        WndClass.style =
CS_HREDRAW|CS_VREDRAW;
        WndClass.lpfnWndProc =
WndProc;
        WndClass.cbClsExtra = 0;
        WndClass.cbWndExtra =
0;
        WndClass.hInstance = hInstance;
        WndClass.hIcon =
LoadIcon(NULL, IDI_APPLICATION);
        WndClass.hCursor = LoadCursor(NULL,
IDC_ARROW);
        WndClass.hbrBackground =
GetStockObject(WHITE_BRUSH);
        WndClass.lpszMenuName =
“MyMenu”;
        WndClass.lpszClassName =
szAppName;
        if(!RegisterClass(&WndClass))
                return
FALSE;

        hWnd =
CreateWindow(
                szAppName,
                szAppName,
                WS_OVERLAPPEDWINDOW,
                CW_USEDEFAULT,
                CW_USEDEFAULT,
                CW_USEDEFAULT,
                CW_USEDEFAULT,
                NULL,
                NULL,
                hInstance,
                NULL
        );

        ShowWindow(hWnd,
nCmdShow);
        UpdateWindow(hWnd);

        while(GetMessage(&msg, NULL, 0,
0))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }

        return msg.wParam;
}

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

        static char cHeader;
        static char
szData[80];

        switch(message)
        {
            case
WM_CREATE :

                cHeader = '
';
                return 0;

            case WM_PAINT :

                hDC = BeginPaint(hWnd,
&ps);
                TextOut(hDC, 100, 100, &cHeader,
1);
                TextOut(hDC, 100, 150, szData,
strlen(szData));
                EndPaint(hWnd,
&ps);
                return 0;

            case WM_COMMAND :

                switch(LOWORD(wParam))
                {
                    case
100 :

                        SaveProc();
                        break;

                    case 200 :

                        LoadProc();
                        cHeader
= GetHeader();
                        strcpy(szData,
GetData());
                        InvalidateRect(hWnd, NULL,
FALSE);
                        break;

                    case 300 :

                        CopyFile(“e:test.txt”,
“e:test1.txt”, FALSE);
                        break;

                    case 400 :

                        MoveFile(“e:test.txt”,
“e:test1.txt”);
                        break;

                    case 500 :

                        DeleteFile(“e:test.txt”);
                        break;
                }
                return
0;

            case WM_DESTROY :

                PostQuitMessage(0);
                return
0;
        }
        return DefWindowProc(hWnd, message, wParam,
lParam);
}

void SaveProc(void)
{
    HANDLE
hFile;
    MYFILE tmpMyFile;
    DWORD dwBuffer;

    tmpMyFile.cHeader =
'A';
    strcpy(tmpMyFile.szData, “This is File Data”);

    hFile = CreateFile(“e:test.txt”,
GENERIC_WRITE, 0, NULL, CREATE_NEW,
        FILE_ATTRIBUTE_NORMAL,
NULL);
    WriteFile(hFile, (char *)&tmpMyFile, sizeof(MYFILE),
&dwBuffer, NULL);
    CloseHandle(hFile);
}

void LoadProc(void)
{
    HANDLE
hFile;
        DWORD dwBuffer;

    hFile = CreateFile(“e:test.txt”,
GENERIC_READ, 0, NULL, OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
NULL);
    ReadFile(hFile, (MYFILE *)&MyFile, sizeof(MYFILE),
&dwBuffer, NULL);
    CloseHandle(hFile);
}

char GetHeader(void)
{
    return
MyFile.cHeader;
}

LPSTR GetData(void)
{
    return
MyFile.szData;
}

너무 간단해서 설명 드릴부분은 없는것 같군요.

case 300 :

    CopyFile(“e:test.txt”, “e:test1.txt”,
FALSE);
    break;

test.txt 파일을 test1.txt 파일로 복사하는 구문입니다.

case 400 :

    MoveFile(“e:test.txt”,
“e:test1.txt”);
    break;

test.txt 파일을 test1.txt 파일로 이름을 바꾸는 구문입니다.

case 500 :

    DeleteFile(“e:test.txt”);
    break;

test.txt 파일을 지우는 구문입니다.

오늘은 여기까지
끝~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`

 

  윈도우 32비트 프로그래밍 38

안녕하세요…………….돌팔이
황동준입니다…………………

이번 시간에는 원하는 파일을 찾는 방법을 알아 보도록 하겠습니다. 윈도우즈용으로 제작된 파일
매니저 프로그램을 보면 전부 이 기능을 기본으로 가지고 있는 것을 보셨을 겁니다. 구현은 그렇게 어렵지 않습니다.

HANDLE FindFirstFile(
    LPCTSTR
 lpFileName,
    LPWIN32_FIND_DATA  lpFindFileData
   );

위 함수를 이용해서 원하는 파일을 찾을 수 있습니다. 첫번째 파라미터에 찾으려는 파일이름을
지정하면 됩니다. 두번째 파라미터에는 WIN32_FIND_DATA라는 구조체 변수의 주소를 지정하면 되는데 이 구조체에는 찾은 파일에 대한
정보가 기록됩니다. 아래는 이 구조체의 원형입니다.

typedef struct _WIN32_FIND_DATA {
    DWORD
dwFileAttributes;
    FILETIME ftCreationTime;
    FILETIME
ftLastAccessTime;
    FILETIME ftLastWriteTime;
    DWORD
   nFileSizeHigh;
    DWORD    nFileSizeLow;
    DWORD
   dwReserved0;
    DWORD    dwReserved1;
    TCHAR    cFileName[ MAX_PATH
];
    TCHAR    cAlternateFileName[ 14 ];
} WIN32_FIND_DATA;

첫번째 맴버인 dwFileAttributes에는 찾은 파일의 속성이 저장되는데 이 부분에
저장될 수 있는 예약어는 다음과 같습니다.

FILE_ATTRIBUTE_ARCHIVE      아카이브 파일을
의미합니다.
FILE_ATTRIBUTE_DIRECTORY    디렉토리를 의미합니다.
FILE_ATTRIBUTE_HIDDEN
      히든 파일을 의미합니다.
FILE_ATTRIBUTE_NORMAL       일반적인 파일을
의미합니다.
FILE_ATTRIBUTE_READONLY     읽기 전용 파일을 의미합니다.
FILE_ATTRIBUTE_SYSTEM
      시스템 파일을 의미합니다.

두번째 맴버인 ftCreationTime에는 파일이 만들어진 시간이 저장되는데 이것에 대한
것은 아래부분에서 다시 언급하도록 하겠습니다.

세번째 맴버인 ftLastAccessTime에는 파일이 가장 최근에 어세스된 시간이
저장되는데 이것에 대한것도 뒤에가서 다시 알아 보겠습니다.

네번째 맴버인 ftLastWriteTime에는 파일이 최근에 수정된 시간이
저장됩니다.

다섯번째 맴버인 nFileSizeHigh에는 파일 크기의 상위워드 값이 저장되고 여섯번째
맴버인 nFileSizeLow에는 파일크기의 하위워드 값이 저장됩니다.

그리고 아홉번째 맴버인 cFileName에는 찾은 파일 이름이 저장됩니다.

우리가 이번에 만들고자 하는 프로그램에서는 굳이 이 구조체 변수를 활용할 필요는 없으나
여러분들이 위 함수를 이용해서 프로그램을 작성한다면 알아 두는 것도 좋을 거라는 생각이 드는군요.

자 그러면 한가지 더 알아 봅시다. 파일 IO 부분을 할때 파일을 열고 나서 나중에 그
파일을 닫았죠? 파일을 찾을 때도 마찬가지입니다. 위 FindFirstFile() 함수는 찾으려는 파일이 처음에 발견되면 그 찾는 포인터가
이동된 상태로 되어 있고 다시 그 파일을 찾으려면 그곳부터 포인터가 이동됩니다. 그러기 때문에 찾는 과정이 끝나면 찾는 것을 닫아 주어야
합니다.

BOOL FindClose(
    HANDLE  hFindFile
   );
  

위 함수를 사용하면 됩니다.

자 그러면 실제로 파일을 찾는 프로그램을 하나 만들어 봅시다. 아주 간단하게 구현할 수
있습니다.

MyMenu MENU
BEGIN
    POPUP
“&File”
    BEGIN
        MENUITEM “&Find”,
100
    END
END

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

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM,
LPARAM);
BOOL SearchFile(char *str);

int WINAPI WinMain
(HINSTANCE hInstance,
HINSTANCE hPrevInstance, LPSTR lpszArg, int nCmdShow)
{
        static
char szAppName[] = “File & Directory Example”;
        HWND
hWnd;
        MSG msg;
        WNDCLASS WndClass;

        WndClass.style =
CS_HREDRAW|CS_VREDRAW;
        WndClass.lpfnWndProc =
WndProc;
        WndClass.cbClsExtra = 0;
        WndClass.cbWndExtra =
0;
        WndClass.hInstance = hInstance;
        WndClass.hIcon =
LoadIcon(NULL, IDI_APPLICATION);
        WndClass.hCursor = LoadCursor(NULL,
IDC_ARROW);
        WndClass.hbrBackground =
GetStockObject(WHITE_BRUSH);
        WndClass.lpszMenuName =
“MyMenu”;
        WndClass.lpszClassName =
szAppName;
        if(!RegisterClass(&WndClass))
                return
FALSE;

        hWnd =
CreateWindow(
                szAppName,
                szAppName,
                WS_OVERLAPPEDWINDOW,
                CW_USEDEFAULT,
                CW_USEDEFAULT,
                CW_USEDEFAULT,
                CW_USEDEFAULT,
                NULL,
                NULL,
                hInstance,
                NULL
        );

        ShowWindow(hWnd,
nCmdShow);
        UpdateWindow(hWnd);

        while(GetMessage(&msg, NULL, 0,
0))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }

        return msg.wParam;
}

LRESULT CALLBACK
WndProc(HWND hWnd, UINT
message, WPARAM wParam, LPARAM lParam)
{
        BOOL bOK;
        char
szFileName[] = “e:srccommtty.cpp”;
        static char szBuff[80];

        switch(message)
        {
            case
WM_COMMAND :

                switch(LOWORD(wParam))
                {
                    case
100 :

                        bOK =
SearchFile(szFileName);
                        if(bOK)
                        {
                            sprintf(szBuff,
“Find %s”, szFileName);
                            MessageBox(hWnd, szBuff,
“”,
MB_OK);
                        }
                        else
                        {
                            sprintf(szBuff,
“Not Found %s”, szFileName);
                            MessageBox(hWnd,
szBuff, “”,
MB_OK);
                        }
                        break;
                }
                return
0;

            case WM_DESTROY :

                PostQuitMessage(0);
                return
0;
        }
        return DefWindowProc(hWnd, message, wParam,
lParam);
}

BOOL SearchFile(char
*str)
{
    WIN32_FIND_DATA ff;
    HANDLE hFile;

    hFile = FindFirstFile(str,
&ff);
    if(hFile !=
INVALID_HANDLE_VALUE)
    {
        FindClose(hFile);
        return
TRUE;
    }
    else
    {
        FindClose(hFile);
        return
FALSE;
    }
}

위 프로그램은 e:srccommtty.cpp 파일을 찾는 프로그램인데 파일을
찾으면 찾았다는 메시지가 출력되고 찾지 못하면 찾지 못했다는 메시지가 출력됩니다.

그러면 구체적으로 프로그램 소스를 보도록 합시다. 제가 만든 SearchFile()이라는
함수의 내용만 보면 되겠네요.

BOOL SearchFile(char
*str)
{
    WIN32_FIND_DATA ff;

위 구조체는 이미 앞에서 설명 드렸을 겁니다. 그러나 이번 프로그램에서는 이 구조체를
사용하지는 않습니다.

    HANDLE hFile;

    hFile = FindFirstFile(str, &ff);

파라미터로 지정된 파일을 찾는 구문입니다.

    if(hFile !=
INVALID_HANDLE_VALUE)
    {
        FindClose(hFile);
        return
TRUE;
    }
    else
    {
        FindClose(hFile);
        return
FALSE;
    }

파일을 찾지 못하면 INVALID_HANDLE_VALUE라는 값을 리턴한다는 것을 보여주고
있습니다. 그렇죠?

}

이해하는데 크게 어려운 점은 없을 겁니다.

오늘은 여기까지
끝~~~~~~~~~~~~~~~~~~~~~~~~~~~

 

  윈도우 32비트 프로그래밍 39

안녕하세요…………….돌팔이
황동준입니다………………

이번시간에도 파일 찾는 프로그램을 하나 만들어 볼텐데 위에서 만든 프로그램보다는 조금 더
많이 사용하는 형식입니다. 주로 유저가 파일을 찾을 때에는 파일 이름을 정확히 기억하는 경우는 없죠. 바로 우리가 흔히 얘기하는 와일드 카드라는
것을 이용해서 파일을 찾는데 이번에는 지정해준 디렉토리내에 있는 모든 파일과 디렉토리를 찾는 프로그램을 만들어 볼려고 합니다.

만들기 전에 함수하나를 더 알아야 합니다. 우리가 앞에서 배운 FindFirstFile()
함수를 이용해서 파일을 찾으면 그 찾는 포인터가 그 만큼 이동된다고 했을 겁니다. 그렇죠? 다음에 계속해서 파일을 찾으려면 이때부터는
FindNextFile()이라는 함수를 사용합니다.

BOOL FindNextFile(
    HANDLE
 hFindFile,
    LPWIN32_FIND_DATA  lpFindFileData
   );

첫번째 파라미터에 FindFirstFile()함수에서 얻은 파일 핸들을 지정하면 되고 두번째
파라미터는 앞에서 알아본 의미와 같습니다. 자 그러면 실제로 프로그램을 만들어 봅시다.

MyMenu MENU
BEGIN
    POPUP
“&File”
    BEGIN
        MENUITEM “&Find”,
100
    END
END

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

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM,
LPARAM);
void SearchFile(HWND hWnd, char *str);

int WINAPI WinMain
(HINSTANCE hInstance,
HINSTANCE hPrevInstance, LPSTR lpszArg, int nCmdShow)
{
        static
char szAppName[] = “File & Directory Example”;
        HWND
hWnd;
        MSG msg;
        WNDCLASS WndClass;

        WndClass.style =
CS_HREDRAW|CS_VREDRAW;
        WndClass.lpfnWndProc =
WndProc;
        WndClass.cbClsExtra = 0;
        WndClass.cbWndExtra =
0;
        WndClass.hInstance = hInstance;
        WndClass.hIcon =
LoadIcon(NULL, IDI_APPLICATION);
        WndClass.hCursor = LoadCursor(NULL,
IDC_ARROW);
        WndClass.hbrBackground =
GetStockObject(WHITE_BRUSH);
        WndClass.lpszMenuName =
“MyMenu”;
        WndClass.lpszClassName =
szAppName;
        if(!RegisterClass(&WndClass))
                return
FALSE;

        hWnd =
CreateWindow(
                szAppName,
                szAppName,
                WS_OVERLAPPEDWINDOW,
                CW_USEDEFAULT,
                CW_USEDEFAULT,
                CW_USEDEFAULT,
                CW_USEDEFAULT,
                NULL,
                NULL,
                hInstance,
                NULL
        );

        ShowWindow(hWnd,
nCmdShow);
        UpdateWindow(hWnd);

        while(GetMessage(&msg, NULL, 0,
0))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }

        return msg.wParam;
}

LRESULT CALLBACK
WndProc(HWND hWnd, UINT
message, WPARAM wParam, LPARAM lParam)
{
        char szFileName[] =
“e:srcaram*.*”;

        switch(message)
        {
            case
WM_COMMAND :

                switch(LOWORD(wParam))
                {
                    case
100 :

                        SearchFile(hWnd,
szFileName);
                        break;
                }
                return
0;

            case WM_DESTROY :

                PostQuitMessage(0);
                return
0;
        }
        return DefWindowProc(hWnd, message, wParam,
lParam);
}

void SearchFile(HWND hWnd, char
*str)
{
    HDC hDC;
    WIN32_FIND_DATA ff;
    HANDLE
hFile;
    BOOL bOK;
    int nY;

    bOK = TRUE;
    nY = 0;

    hDC = GetDC(hWnd);
    hFile =
FindFirstFile(str, &ff);
    while(bOK && (hFile !=
INVALID_HANDLE_VALUE))
    {
        TextOut(hDC, 0, 20*nY, ff.cFileName,
strlen(ff.cFileName));
        bOK = FindNextFile(hFile,
&ff);
        nY++;
    }
    FindClose(hFile);
    ReleaseDC(hWnd,
hDC);
}

위 프로그램은 e:srcaram디렉토리내에 있는 모든 파일과 디렉토리를 찾는
프로그램입니다. 자 이번에도 제가 만든 SearchFile()이라는 함수의 내용만 보면 될 것 같군요.

void SearchFile(HWND hWnd, char
*str)
{
    HDC hDC;
    WIN32_FIND_DATA ff;
    HANDLE
hFile;
    BOOL bOK;
    int nY;

    bOK = TRUE;

아래에 보면 while문이 있는데 처음에 파일을 찾으면 이 구문안을 실행하기 위해서
TRUE로 세팅한 것입니다.

    nY = 0;

    hDC = GetDC(hWnd);
    hFile =
FindFirstFile(str, &ff);

처음에 파일을 찾으면 while문이 실행되서 찾은 파일이나 디렉토리가 화면에 출력될
것입니다.

    while(bOK && (hFile !=
INVALID_HANDLE_VALUE))
    {
        TextOut(hDC, 0, 20*nY, ff.cFileName,
strlen(ff.cFileName));

구조체 맴버중 cFileName에 찾은 파일이나 디렉토리 이름이 저장된다고 앞에서 설명드렸을
겁니다.

        bOK = FindNextFile(hFile, &ff);

계속해서 파일을 찾아나가고 있습니다. 파일이나 디렉토리를 찾으면 TRUE가
리턴됩니다.
        nY++;
    }
    FindClose(hFile);
    ReleaseDC(hWnd,
hDC);
}

그렇게 복잡하지는 않죠?

오늘은 여기까지
끝~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 

  윈도우 32비트 프로그래밍 40

안녕하세요…………..돌팔이 황동준입니다………………

이번시간에는 파일 정보를 알아 내는 방법을 알아 보겠습니다. 다양한 정보를 얻을 수 있도록
API 함수를 제공하지만 가장 많이 사용하는 파일의 크기와 시간에 대한 정보를 읽어오는 방법에 대한 것만 알아 보겠습니다. 파일의 크기는 그렇다
치고 파일 시간은 크게 세가지 시간으로 나눌 수 있습니다. 그것은 바로 파일이 만들어진 시간, 엑세스된 시간, 그리고 마지막으로 수정된 시간인데
우리가 흔히 알고 있는 시간으로 결과를 얻는 과정이 조금 복잡합니다. 그렇다고 아주 복잡한 것은 아니니 염려할 필요는 없습니다. 먼저 파일의
크기를 얻는 방법을 알아 봅시다. 파일의 크기를 얻을 때에는 간단하게 함수 하나를 이용해서 할 수 있습니다.

DWORD GetFileSize(HANDLE hFile, LPDWORD
lpdwFileSizeHigh);

위 함수를 이용하면 파일의 크기를 리턴받을 수 있는데 첫번째 파라미터에 파일의 핸들을 지정해
주고 두번째 파라미터에는 보통 NULL을 지정해 주면 됩니다.

자 그러면 파일이 가지고 있는 시간에 대한 정보를 얻는 방법을 알아 봅시다.

BOOL GetFileTime(
    HANDLE
 hFile,
    LPFILETIME  lpftCreation,
    LPFILETIME
 lpftLastAccess,
    LPFILETIME  lpftLastWrite
   );

위 함수를 이용해서 시간에 대한 정보를 읽어올 수 있는데 첫번째 파라미터는 당연히 파일의
핸들을 의미합니다. 두번째 파라미터는 파일이 생성된 시간이 저장될 FILETIME 구조체 변수의 주소를 지정하면 되고 세번째는 어세스된 시간,
네번째는 파일이 수정된 시간이 저장될 FILETIME 구조체 변수의 주소를 지정해 주면 됩니다.

아래는 FILETIME 구조체의 원형입니다.

typedef struct _FILETIME {
    DWORD
dwLowDateTime;
    DWORD dwHighDateTime;
} FILETIME;

첫번째 맴버는 시간의 하위 비트를 의미하고 두번째 맴버는 상위 비트를 의미합니다.

위 GetFileTime()함수로 원하는 시간을 얻었다면 다 된 것일까요? 그렇지 않습니다.
왜냐하면 FILETIME에 저장된 시간 정보는 우리가 잘 알아 볼 수 없는 64비트 형식으로 되어 있기 때문입니다. 이것을 우리가 알아 볼 수
있는 형태로 쪼개야(?) 합니다. 이때 사용하는 함수가 바로 아래 함수입니다.

BOOL FileTimeToSystemTime(
    CONST FILETIME *
 lpft,
    LPSYSTEMTIME  lpst
   );

첫번째 파라미터로 우리가 쪼갤(?) FILETIME 구조체 변수입니다. 두번째 파라미터에는
우리가 알아 볼 수 있는 형태로 저장할 구조채 변수의 주소를 지정하면 되는데 이 때 사용하는 구조채가 바로 아래의 SYSTEMTIME이라는
구조체입니다.

typedef struct _SYSTEMTIME {
    WORD
wYear;
    WORD wMonth;
    WORD wDayOfWeek;
    WORD wDay;
    WORD
wHour;
    WORD wMinute;
    WORD wSecond;
    WORD wMilliseconds;
}
SYSTEMTIME;

각 맴버가 무엇을 의미하는지 설명드리지 않아도 알겠죠? 맴버 이름이 잘 정해져있군요.

자 그러면 우리가 배운것을 이용해서 프로그램을 만들어 봅시다.

MyMenu MENU
BEGIN
    POPUP
“&File”
    BEGIN
        MENUITEM “&Save”,
100
        MENUITEM SEPARATOR
        MENUITEM “File Si&ze”,
200
        MENUITEM “File &Time”, 300
    END
END

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

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM,
LPARAM);
void SaveProc(void);
void GetTextFileSize(HWND hWnd);
void
GetTextFileTime(HWND hWnd);

typedef struct tagMYFILE
{
    char
cHeader;
    char szData[80];
} MYFILE;

int WINAPI WinMain
(HINSTANCE hInstance,
HINSTANCE hPrevInstance, LPSTR lpszArg, int nCmdShow)
{
        static
char szAppName[] = “File & Directory Example”;
        HWND
hWnd;
        MSG msg;
        WNDCLASS WndClass;

        WndClass.style =
CS_HREDRAW|CS_VREDRAW;
        WndClass.lpfnWndProc =
WndProc;
        WndClass.cbClsExtra = 0;
        WndClass.cbWndExtra =
0;
        WndClass.hInstance = hInstance;
        WndClass.hIcon =
LoadIcon(NULL, IDI_APPLICATION);
        WndClass.hCursor = LoadCursor(NULL,
IDC_ARROW);
        WndClass.hbrBackground =
GetStockObject(WHITE_BRUSH);
        WndClass.lpszMenuName =
“MyMenu”;
        WndClass.lpszClassName =
szAppName;
        if(!RegisterClass(&WndClass))
                return
FALSE;

        hWnd =
CreateWindow(
                szAppName,
                szAppName,
                WS_OVERLAPPEDWINDOW,
                CW_USEDEFAULT,
                CW_USEDEFAULT,
                CW_USEDEFAULT,
                CW_USEDEFAULT,
                NULL,
                NULL,
                hInstance,
                NULL
        );

        ShowWindow(hWnd,
nCmdShow);
        UpdateWindow(hWnd);

        while(GetMessage(&msg, NULL, 0,
0))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }

        return msg.wParam;
}

LRESULT CALLBACK
WndProc(HWND hWnd, UINT
message, WPARAM wParam, LPARAM
lParam)
{
        switch(message)
        {
            case
WM_COMMAND :

                switch(LOWORD(wParam))
                {
                    case
100 :

                        SaveProc();
                        break;

                    case 200 :

                        GetTextFileSize(hWnd);
                        break;

                    case 300 :

                        GetTextFileTime(hWnd);
                        break;
                }
                return
0;

            case WM_DESTROY :

                PostQuitMessage(0);
                return
0;
        }
        return DefWindowProc(hWnd, message, wParam,
lParam);
}

void SaveProc(void)
{
    HANDLE
hFile;
    MYFILE tmpMyFile;
    DWORD dwBuffer;

    tmpMyFile.cHeader =
'A';
    strcpy(tmpMyFile.szData, “This is File Data”);

    hFile = CreateFile(“e:test.txt”,
GENERIC_WRITE, 0, NULL, CREATE_NEW,
        FILE_ATTRIBUTE_NORMAL,
NULL);
    WriteFile(hFile, (char *)&tmpMyFile, sizeof(MYFILE),
&dwBuffer, NULL);
    CloseHandle(hFile);
}

void GetTextFileSize(HWND hWnd)
{
    HANDLE
hFile;
    HDC hDC;
    DWORD dwSize;
    static char szBuff[80];

    hFile = CreateFile(“e:test.txt”,
GENERIC_READ, 0, NULL, OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
NULL);
    dwSize = GetFileSize(hFile,
NULL);
    CloseHandle(hFile);
    sprintf(szBuff, “This File is %d
bytes”, dwSize);
    hDC = GetDC(hWnd);
    TextOut(hDC, 100, 80, szBuff,
strlen(szBuff));
    ReleaseDC(hWnd, hDC);
}

void GetTextFileTime(HWND hWnd)
{
    HANDLE
hFile;
    HDC hDC;
    FILETIME CreateFileTime, AccessFileTime,
ModifyFileTime;
    SYSTEMTIME sysTime;
    static char szBuff1[256],
szBuff2[256], szBuff3[256];

    hFile = CreateFile(“e:test.txt”,
GENERIC_READ, 0, NULL, OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
NULL);
    GetFileTime(hFile, &CreateFileTime, &AccessFileTime,
&ModifyFileTime);
    CloseHandle(hFile);

    FileTimeToSystemTime(&CreateFileTime,
&sysTime);

    sprintf(szBuff1, “This File is Created Year :
%d Month : %d Day : %d
        Hour : %d Min : %d Sec : %d”, sysTime.wYear,
sysTime.wMonth,
        sysTime.wDay, sysTime.wHour, sysTime.wMinute,
sysTime.wSecond);

    FileTimeToSystemTime(&AccessFileTime,
&sysTime);

    sprintf(szBuff2, “This File is Accessed Year :
%d Month : %d Day : %d
        Hour : %d Min : %d Sec : %d”, sysTime.wYear,
sysTime.wMonth,
        sysTime.wDay, sysTime.wHour, sysTime.wMinute,
sysTime.wSecond);

    FileTimeToSystemTime(&ModifyFileTime,
&sysTime);

    sprintf(szBuff3, “This File is Modified Year :
%d Month : %d Day : %d
        Hour : %d Min : %d Sec : %d”, sysTime.wYear,
sysTime.wMonth,
        sysTime.wDay, sysTime.wHour, sysTime.wMinute,
sysTime.wSecond);

    hDC = GetDC(hWnd);
    TextOut(hDC, 100,
100, szBuff1, strlen(szBuff1));
    TextOut(hDC, 100, 120, szBuff2,
strlen(szBuff2));
    TextOut(hDC, 100, 140, szBuff3,
strlen(szBuff3));
    ReleaseDC(hWnd, hDC);
}

제가 만든 함수 두개만 알아 보면 되겠네요.

void GetTextFileSize(HWND hWnd)
{

이 함수는 파일의 크기를 얻어서 그 값을 화면에 출력하는 역할을 합니다.

    HANDLE hFile;
    HDC hDC;
    DWORD
dwSize;
    static char szBuff[80];

    hFile = CreateFile(“e:test.txt”,
GENERIC_READ, 0, NULL, OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
NULL);

파일 크기를 얻기 위한 GetFileSize()함수의 첫번째 파라미터가 파일 핸들을
요구하므로 위 함수를 사용했습니다.

    dwSize = GetFileSize(hFile, NULL);

파일 크기를 얻고 있는 과정입니다.

    CloseHandle(hFile);
    sprintf(szBuff,
“This File is %d bytes”, dwSize);
    hDC = GetDC(hWnd);
    TextOut(hDC,
100, 80, szBuff, strlen(szBuff));
    ReleaseDC(hWnd, hDC);

얻은 파일크기를 화면에 출력하고 있습니다.

}

void GetTextFileTime(HWND hWnd)
{

이 함수는 파일이 생성된 시간, 어세스된 시간, 수정된 시간을 얻어서 그 시간을 화면에
출력해주는 역할을 합니다.

    HANDLE hFile;
    HDC hDC;
    FILETIME
CreateFileTime, AccessFileTime, ModifyFileTime;
    SYSTEMTIME
sysTime;
    static char szBuff1[256], szBuff2[256], szBuff3[256];

    hFile = CreateFile(“e:test.txt”,
GENERIC_READ, 0, NULL, OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
NULL);

시간을 얻기 위한 GetFileTime()함수의 첫번째 파라미터가 파일핸들을 요구하므로 위
구문을 사용했습니다.

    GetFileTime(hFile, &CreateFileTime,
&AccessFileTime, &ModifyFileTime);

시간 정보를 얻고 있는 구문입니다.

    CloseHandle(hFile);

    FileTimeToSystemTime(&CreateFileTime,
&sysTime);

64비트 시간 정보를 알아볼수 있는 시간 형태로 변환하고 있습니다.

    sprintf(szBuff1, “This File is Created Year :
%d Month : %d Day : %d
        Hour : %d Min : %d Sec : %d”, sysTime.wYear,
sysTime.wMonth,
        sysTime.wDay, sysTime.wHour, sysTime.wMinute,
sysTime.wSecond);

    FileTimeToSystemTime(&AccessFileTime,
&sysTime);

64비트 시간 정보를 알아볼수 있는 시간 형태로 변환하고 있습니다.

    sprintf(szBuff2, “This File is Accessed Year :
%d Month : %d Day : %d
        Hour : %d Min : %d Sec : %d”, sysTime.wYear,
sysTime.wMonth,
        sysTime.wDay, sysTime.wHour, sysTime.wMinute,
sysTime.wSecond);

    FileTimeToSystemTime(&ModifyFileTime,
&sysTime);

64비트 시간 정보를 알아볼수 있는 시간 형태로 변환하고 있습니다.

    sprintf(szBuff3, “This File is Modified Year :
%d Month : %d Day : %d
        Hour : %d Min : %d Sec : %d”, sysTime.wYear,
sysTime.wMonth,
        sysTime.wDay, sysTime.wHour, sysTime.wMinute,
sysTime.wSecond);

    hDC = GetDC(hWnd);
    TextOut(hDC, 100,
100, szBuff1, strlen(szBuff1));
    TextOut(hDC, 100, 120, szBuff2,
strlen(szBuff2));
    TextOut(hDC, 100, 140, szBuff3,
strlen(szBuff3));
    ReleaseDC(hWnd, hDC);

변환된 시간을 화면에 출력하고 있습니다.

}

오늘은 여기까지
끝~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

zemna

Programmer/Web/Mobile/Desktop

You may also like...

Leave a Reply