본문 바로가기
프로그래밍/Windows

[Windows] 윈도우 로그인 배경화면 변경

by Hwan,. 2016. 9. 17.
728x90
반응형

[기본 지식]

 - 로그인 배경화면 변경 방법

 - 관리자 권한 요구

 - 파일열기 대화상자

 - 레지스트리 변경 방법

 

[Example Source]

#include <windows.h>
#include <stdio.h>
#include "ShReg.h" // Windows API정복 책 참조

#define KEY L"SOFTWARE\\Microsoft\\windows\\CurrentVersion\\Authentication\\LogonUI\\Background" 
#define PATH L"C:\\windows\\system32\\oobe\\info\\backgrounds\\backgroundDefault.jpg"
#define DIRPATH L"C:\\windows\\system32\\oobe\\info\\backgrounds"

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
HINSTANCE g_Inst;
LPCWSTR lpszClass = TEXT("Window");

// http://blog.naver.com/PostView.nhn?blogId=dolicom&logNo=10096040743 참조
void CreateDir(WCHAR* Path)
{
    WCHAR DirName[256];  //생성할 디렉초리 이름
    WCHAR* p = Path;     //인자로 받은 디렉토리
    WCHAR* q = DirName;  

    while(*p)
    {
        if (('\\' == *p) || ('/' == *p))   //루트디렉토리 혹은 Sub디렉토리
        {
            if (':' != *(p-1))
            {
                CreateDirectory(DirName, NULL);
            }
        }
        *q++ = *p++;
        *q = '\0';
    }
    CreateDirectory(DirName, NULL);  
}

// WinMain 생략

LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
    static HANDLE hFile;
    HANDLE hFile_new;
    DWORD numWritten;
    static DWORD nFileSize;
    OPENFILENAME OFN;
    TCHAR lpstrFile[MAX_PATH] = L"";

    static HDC hdc;
    PAINTSTRUCT ps;
    static BOOL file_state;
    static WCHAR str[100];

    static char *buf;
    DWORD readn; 

    switch(iMessage)
    {
    case WM_CREATE:
        CreateWindow(L"button", L"Image Select", WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON, 10, 10, 150, 25, hWnd, (HMENU)1, g_Inst, NULL);
        CreateWindow(L"button", L"convert Background", WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON, 10, 40, 150, 25, hWnd, (HMENU)2, g_Inst, NULL);
        file_state = FALSE;
        CreateDir(DIRPATH); // DIRPATH 경로에 디렉토리가 없다면 생성 (부모 디렉토리가 없어도 알아서 생성)
        break;

    case WM_COMMAND:
        switch(LOWORD(wParam))
        {
        case 1:
            memset(&OFN, 0, sizeof(OPENFILENAME));
            OFN.lStructSize = sizeof(OPENFILENAME);
            OFN.hwndOwner=hWnd;
            OFN.lpstrFilter=TEXT("jpg\0*.jpg\0");
            OFN.lpstrFile=lpstrFile;
            OFN.nMaxFile=MAX_PATH;

            if(GetOpenFileName(&OFN) != 0)
            {
                if( (hFile = CreateFile(OFN.lpstrFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL)) != INVALID_HANDLE_VALUE)
                {
                    
                    if((nFileSize = GetFileSize(hFile, NULL)) >= 256000) // 파일 사이즈 검사
                    {
                        MessageBox(hWnd, L"File size is too big \"Below 256kb\"", L"Error", MB_OK);
                        DestroyWindow(hWnd);
                    }

                    buf = (char*) malloc (nFileSize); // 파일 사이즈 만큼 할당
                    ReadFile(hFile, buf, nFileSize, &readn, NULL); // 파일 사이즈 만큼 읽어옴
                    
                    file_state = TRUE;
                    
                    swprintf_s(str, 100, L"%s", OFN.lpstrFile);
                    InvalidateRect(hWnd, NULL, TRUE);
                }
            }
            break;
        case 2:
            if(file_state != FALSE) // 파일이 열려있는지 확인
            {
                // 파일을 쓰기위해 핸들을 얻어옴 (PATH에 해당하는 파일이 없다면 생성)
                if( (hFile_new = CreateFile(PATH, GENERIC_ALL, 0, NULL, CREATE_ALWAYS, 0, NULL)) != INVALID_HANDLE_VALUE)
                {
                    // PATH에 아까 열었던 이미지파일을 써줌
                    if( WriteFile(hFile_new, buf, nFileSize, &numWritten, NULL) != 0)
                        MessageBox(hWnd, L"File Write Success", 0, MB_OK);
                    else
                        MessageBox(hWnd, L"File Write Failed", 0, MB_OK);
                
                    free(buf);
                    DestroyWindow(hWnd);
                }
                SHRegWriteInt(SHLM, KEY, L"OEMBackground", 1); 
 // 레지스트리 경로 내부의 OEMBackground를 1로 변경 (PATH를 배경으로 사용하겠다는 의미)
            }
            else
            {
                MessageBox(0, L"File open Failed", 0, 0);
            }
        } 
        break;

    case WM_PAINT:
        hdc = BeginPaint(hWnd , &ps);
        
        TextOut(hdc, 170, 10, str, WideCharToMultiByte( CP_ACP, 0, str, -1, NULL, 0, NULL, NULL )-1); 
 // 유니코드 문자열의 사이즈를 구하기 위해 WideCharToMultiByte() 사용

        EndPaint(hWnd, NULL);
        break;

    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hWnd, iMessage, wParam,lParam);
}

 

 

728x90
반응형

댓글