기술나눔

"Windows API 일상 연습" 9.1.5 사용자 지정 리소스

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

사용자 정의 리소스는 Windows 프로그램에서 응용 프로그램별 데이터, 이미지, 오디오, 바이너리 파일 등을 저장하는 데 사용되는 리소스 유형입니다. 개발자는 맞춤형 리소스를 통해 애플리케이션에 필요한 다양한 리소스 파일을 중앙에서 관리하고 저장할 수 있어 프로그램에서 쉽게 접근하고 사용할 수 있습니다.

사용자 정의 리소스에 대한 몇 가지 주요 사항은 다음과 같습니다.

●맞춤형 리소스 유형:

1. 사용자 정의 리소스는 이미지, 오디오, XML 구성 파일, 텍스트 파일 등과 같은 애플리케이션별 데이터 또는 파일일 수 있습니다.

2. 사용자 정의 리소스는 "MY_CUSTOM_RESOURCE"와 같은 사용자 정의 리소스 유형 식별자를 사용하여 식별할 수 있습니다.

●맞춤형 리소스 생성 및 편집:

1. 사용자 정의 리소스는 일반적으로 애플리케이션의 리소스 파일(.rc)에 포함됩니다.

2. Visual Studio의 리소스 뷰와 같은 리소스 편집기를 사용하여 사용자 지정 리소스를 만들고 편집할 수 있습니다.

삼. 리소스 파일에서 각 리소스에 대한 고유한 리소스 식별자와 해당 리소스 파일 경로를 지정할 수 있습니다.

●맞춤형 리소스 참조 및 사용:

1. 코드에서 사용자 지정 리소스를 참조하고 사용할 때 리소스 식별자를 사용하여 해당 리소스를 로드하거나 액세스할 수 있습니다.

2. 해당 API 함수(예: LoadResource, FindResource, LockResource 등)를 사용하여 사용자 정의 리소스를 로드하고 운영합니다.

삼. 사용자 정의 리소스 유형에 따라 다양한 API 기능(예: 이미지 리소스는 GDI 기능을 사용할 수 있고 오디오 리소스는 DirectSound 기능을 사용할 수 있음)을 사용하여 사용자 정의 리소스를 처리할 수 있습니다.

■다음은 사용자 정의 리소스를 로드하고 사용하는 방법을 보여주는 샘플 코드 조각입니다.

#포함하다<Windows.h>

int 메인()

{

HINSTANCE hInstance = GetModuleHandle(NULL) // 현재 인스턴스 핸들을 가져옵니다.

HRSRC hResource = FindResource(hInstance, MAKEINTRESOURCE(IDR_MY_RESOURCE), "MY_CUSTOM_RESOURCE") // 사용자 정의 리소스 찾기

HGLOBAL hResData = LoadResource(hInstance, hResource) // 사용자 정의 리소스 로드

LPVOID pData = LockResource(hResData); // 사용자 정의 리소스 잠금

// 사용자 정의 리소스 사용...

0을 반환합니다.

}

위의 예에서 IDR_MY_RESOURCE는 사용자 정의 리소스의 식별자이며 해당 리소스 파일 경로는 리소스 파일에 정의되어 있습니다. FindResource 함수를 사용하여 사용자 정의 리소스를 찾은 다음 LoadResource 함수를 사용하여 사용자 정의 리소스를 로드하고 마지막으로 LockResource 함수를 사용하여 사용자 정의 리소스를 잠그고 리소스 데이터에 대한 포인터를 얻습니다. 이후 포인터 pData는 리소스의 유형과 요구 사항에 따라 후속 처리 및 작업에 사용될 수 있습니다.

사용자 정의 리소스가 사용되는 방식은 리소스 유형과 애플리케이션의 요구 사항에 따라 다르다는 점에 유의하는 것이 중요합니다. 개발자는 적절한 리소스 유형과 해당 API 기능을 선택하여 실제 요구 사항에 따라 사용자 지정 리소스를 처리할 수 있습니다.

사용자 정의 리소스는 애플리케이션에 대한 유연한 리소스 관리 방법을 제공합니다. 애플리케이션에 필요한 다양한 데이터와 파일을 프로그램 내에서 균일하고 쉽게 접근하고 사용할 수 있습니다. 사용자 지정 리소스를 사용하면 애플리케이션을 더욱 모듈화하고, 유지 관리 및 확장 가능하게 만들 수 있습니다.

       ■VS에서사용자 정의 리소스 추가

1. 리소스 추가

2. "사용자 정의"를 클릭하고 리소스 유형 "TEXT"를 입력합니다.

3. 리소스를 가져오고 text1.bin 파일을 자동으로 생성합니다. 리소스 ID: IDR_TEXT1

4. VS에서는 사용자 정의 컴파일러에 리소스 파일 이름을 직접 입력하고 ID를 수정합니다. 오류 메시지가 나타납니다. 외부 리소스를 로드할 수 없습니다. 리소스를 가져오지 못했기 때문일 수 있습니다.

5. 리소스 보기 상자에 리소스를 추가합니다.

6. 외부 리소스 파일을 가져옵니다.

7. 리소스 파일 이름과 ID를 다시 입력합니다. ID 이름은 따옴표 붙은 문자열 "ANNABELLEE"로 입력해야 합니다.

8. 설정을 저장하면 됩니다.

 

더 간단한 방법은 리소스 파일 POEPOEM.rc를 직접 수정하는 것입니다. TEXT 아래 줄 아래에 리소스를 추가하기만 하면 됩니다.

      

9.1.6 연습 57: 문자열 리소스 테이블과 사용자 정의 리소스

/*------------------------------------------------------------------------

057 WIN32 API 매일 연습하세요

     예제 57 POEPOEM.C: 문자열 리소스 테이블 및 사용자 지정 리소스

로드스트링 기능

로드리소스 기능

리소스 찾기 기능

잠금 리소스 기능

안시넥스트 매크로 정의

(c) www.bcdaren.com 프로그램 제작자

-----------------------------------------------------------------------*/

#포함하다 <windows.h>

#포함하다 "리소스.h"

결과 콜백 윈도우 프로세스 (한국어, 단위, W파라미터, L파라미터) ;

예시 hInst ;

정수 윈에이피(WINAPI) 윈메인 (예시 인스턴스, 예시 hPrev인스턴스,

 PSTR szCmdLine, 정수 아이씨엠디쇼)

{   //리소스 파일 이름, 제목 및 오류 메시지

     차르 szAppName[16], sz캡션[64], 오류메시지[64];

     한국어 hwnd;

     MSG 메시지;

     WND클래스 wnd클래스;

     //문자열 리소스 로드

     로드스트링(인스턴스, IDS_앱 이름, szAppName,

          크기의(szAppName) / 크기의(차르));

     로드스트링(인스턴스, IDS_캡션, sz캡션,

          크기의(sz캡션) / 크기의(차르));

     wnd클래스.스타일 = CS_HREDRAW | CS_VREDRAW;

     wnd클래스.lpfnWndProc = 윈도우 프로세스;

     wnd클래스.cbCls엑스트라 = 0;

     wnd클래스.cbWndExtra = 0;

     wnd클래스.인스턴스 = 인스턴스;

//아이콘 추가

     wnd클래스.아이콘 = 로드아이콘(인스턴스, 메이크인트레소스(아이디_아이콘1));

     //wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);

//사용자 정의 마우스 포인터

     wnd클래스.h커서 = 로드커서(인스턴스,메이크인트레소스(IDC_커서1));

     wnd클래스.hbr배경 = (에이치브러쉬)GetStockObject(화이트_브러쉬);

     wnd클래스.lpsz메뉴이름 = 없는;

     wnd클래스.lpsz클래스 이름 = szAppName;

     //hInst = hInstance;//원본 코드에 없으므로 오류가 보고되지 않습니다.

     만약에 (!등록클래스(&wnd클래스))

     {

          //LoadStringA(hInstance, IDS_APPNAME, (char *)szAppName,

          // sizeof(szAppName));

          로드문자열A(인스턴스, IDS_ERRMSG, ( *)오류메시지,

               크기의(오류메시지));

          메시지 상자A(없는, ( *)오류메시지,

               ( *)szAppName,

               MB_아이콘 오류);

          반품 0;

     }

     hwnd = CreateWindow(szAppName, sz캡션,

          WS_오버랩 윈도우 | WS_클립아이들,

          CW_사용기본값, CW_사용기본값,

          CW_사용기본값, CW_사용기본값,

          없는, 없는, 인스턴스, 없는);

     쇼윈도우(hwnd, 아이씨엠디쇼);

     업데이트 창(hwnd);

     ~하는 동안 (메시지를 받으세요(&메시지, 없는, 0, 0))

     {

          번역메시지(&메시지);

          발송메시지(&메시지);

     }

     반품 메시지.w파라미터;

}

결과 콜백 윈도우 프로세스 ( 한국어 hwnd, 단위 메시지, W파라미터 w파라미터, L파라미터

l파라미터)

{

     //정적 char * pText;

     공전 LPCSTR 텍스트;

     공전 에이치글로벌 h리소스;//리소스 핸들 - 메모리 블록을 가리키는 핸들

     공전 한국어 h스크롤;

     공전 정수 아이포지션, cxChar, 사이차, cy클라이언트,

          iNum줄, 스크롤;

     HDC HDC (에이치디씨);

     페인트스트럭트 추신;

     직각 직사각형;

     텍스트메트릭 티엠;

     스위치 (메시지)

     {

     사례 WM_생성:

          HDC (에이치디씨) = GetDC(hwnd);

          GetTextMetrics(HDC (에이치디씨), &티엠);

          cxChar = 티엠.tmAveCharWidth;

          사이차 = 티엠.tm높이 + 티엠.tm외부선도;

          릴리스DC(hwnd, HDC (에이치디씨));

//세로 스크롤 막대의 너비(픽셀)

          스크롤 = GetSystemMetrics(SM_CXV스크롤);

          //스크롤바 생성

          h스크롤 = CreateWindow(텍스트("스크롤 바"), 없는,

               WS_어린이 | WS_표시됨 | SBS_VERT,

               0, 0, 0, 0,

               hwnd, (메뉴)1, hInst, 없는);

          //텍스트 핸들 가져오기

          h리소스 = 로드리소스(hInst,

               리소스 찾기(hInst, 텍스트("애너벨리"),//지정된 유형과 이름이 있는지 확인하세요.

지정된 모듈의 리소스 위치

                    텍스트("텍스트")));

          //메모리에서 지정된 리소스에 대한 포인터를 검색합니다.

          텍스트 = (LPCSTR)잠금 리소스(h리소스);

          iNum줄 = 0;//텍스트 줄 수 읽기

          //텍스트 줄 수를 가져옵니다.

          ~하는 동안 (*텍스트 != '\' && *텍스트 != '0')//또는 0으로 끝남

          {

               만약에 (*텍스트 == 'N')

                    iNum줄++;

                //16비트 Windows에서 ansi 문자열 AnsiNext의 다음 위치(포인터)를 반환합니다.

//매크로 정의인 Win32는 대신 CharNext를 사용합니다(AnsiNext는 ansi 문자만 처리할 수 있습니다).

//String; CharNext는 ansi 또는 유니코드 문자열일 수 있습니다.

                //pText = AnsiNext(pText);

               텍스트 = (LPCSTR)다음((한국어:)텍스트);

          }

     //*pText = '0';//여기의 원본 코드는 null 문자로 끝나는 것으로 나와 있습니다. 실제 텍스트는 null 문자로 끝나지 않습니다.

          //스크롤바 설정

          스크롤 범위 설정(h스크롤, SB_CTL, 0, iNum줄, 거짓);

          스크롤 위치 설정(h스크롤, SB_CTL, 0, 거짓);

          반품 0;

     사례 WM_크기:

          창 이동(h스크롤, 로우워드(l파라미터) - 스크롤, 0,

               스크롤, cy클라이언트 = 하이워드(l파라미터), 진실);

          초점 맞추기(hwnd);//초점 설정

          반품 0;

     사례 WM_초점 설정:

          초점 맞추기(h스크롤);//스크롤바 슬라이더 포커스 캡처

          반품 0;

     사례 WM_VSCROLL:

          스위치 (로우워드(w파라미터))  //알림 코드가 낮은 단어에 있으므로 LOWORD를 추가해야 합니다.

          {

          사례 SB_TOP:

               아이포지션 = 0;

               부서지다;

          사례 SB_바닥:

               아이포지션 = iNum줄;

               부서지다;

          사례 SB_라인업:

               아이포지션 -= 1;

               부서지다;

          사례 SB_라인다운:

               아이포지션 += 1;

               부서지다;

          사례 SB_페이지업:

               아이포지션 -= cy클라이언트 / 사이차;

               부서지다;

          사례 SB_페이지 다운:

               아이포지션 += cy클라이언트 / 사이차;

               부서지다;

          사례 SB_썸트랙:

               아이포지션 = 하이워드(w파라미터);

               부서지다;

          }

          아이포지션 = 최대(0, (아이포지션, iNum줄));

          만약에 (아이포지션 != 스크롤 위치 가져오기(h스크롤, SB_CTL))

          {

               스크롤 위치 설정(h스크롤, SB_CTL, 아이포지션, 진실);

               무효화직사각형(hwnd, 없는, 진실);

          }

          반품 0;

     사례 WM_페인트:

          HDC (에이치디씨) = 페인트 시작(hwnd, &추신);

          텍스트 = ( *)잠금 리소스(h리소스);

          GetClientRect(hwnd, &직사각형);

          직사각형.왼쪽 += cxChar;//2열부터 표시

          직사각형.맨 위 += 사이차 * (1 - 아이포지션);

          // 글꼴 외부 줄 행간 높이를 포함합니다. 일반적으로 외부 줄 헤더는 텍스트 줄 높이에 포함되지 않습니다.

          그리기텍스트A(HDC (에이치디씨), 텍스트, -1, &직사각형, DT_외부리딩);

          엔드페인트(hwnd, &추신);

          반품 0;

     사례 WM 파괴:

          무료 리소스(h리소스);

          게시물 종료 메시지(0);

          반품 0;

     }

     반품 DefWindowProc(hwnd, 메시지, w파라미터, l파라미터);

}

/******************************************************************************

로드스트링 기능: 문자열 리소스를 로드한 다음 문자열을 종료 null 문자가 있는 버퍼에 복사합니다.

또는 문자열 리소스 자체에 대한 읽기 전용 포인터를 반환합니다.

*******************************************************************************

로드리소스 기능: 메모리에 있는 지정된 리소스의 첫 번째 바이트에 대한 포인터를 얻는 데 사용할 수 있는 핸들을 검색합니다.

HGLOBAL 로드리소스(

HMODULE h모듈,// 실행 파일에 리소스가 포함된 모듈에 대한 핸들입니다.hModule이 NULL이면 시스템은 현재 프로세스를 생성하는 데 사용된 모듈에서 리소스를 로드합니다.

HRSRC hResInfo//로드할 리소스에 대한 핸들

);

*******************************************************************************

리소스 찾기 기능: 지정된 모듈에서 지정된 유형 및 이름의 리소스 위치를 결정합니다.

HRSRC FindResourceA(

HMODULE h모듈,//리소스가 포함된 모듈에 대한 핸들

LPCSTR lpName,//리소스 이름

LPCSTR lpType//자원 유형

);

*******************************************************************************

잠금 리소스 기능: 메모리에서 지정된 리소스에 대한 포인터를 검색합니다.

LPVOID 잠금 리소스(

HGLOBAL hResData//접근할 리소스에 대한 핸들

);

*******************************************************************************

안시넥스트 매크로 정의:

16ANSI 문자열만 처리할 수 있는 Windows의 API 함수(정확히 말하면 매크로 정의)입니다.

나중에 Win32가 등장했을 때 Microsoft는 호환성을 위해 CharNext를 통해 캡슐화를 구현했습니다.

다음ANSI 또는 유니코드 문자열일 수 있습니다.

이 함수는 ansi 문자열의 다음 위치(포인터)를 반환합니다.

*/

리소스.h헤드 파일

//{{종속성 없음}}

// 마이크로소프트 비주얼 C++ 생성된 포함 파일.

// 057_POEPOEM.rc에서 사용

//

#IDS_APPNAME 1을 정의합니다.

#IDS_캡션 2 정의

#IDS_CAPTION 3을 정의합니다.

#IDS_ERRMSG 4를 정의합니다.

#IDI_ICON1을 1로 정의합니다.

#IDC_CURSOR1 2를 정의합니다.

#IDR_TEXT1 정의 107

#IDR_TEXT2 정의 108

// 새 객체에 대한 다음 기본값

//

#ifdef APSTUDIO_INVOKED

#ifndef APSTUDIO_READONLY_SYMBOLS

#APS_다음_리소스_값_126을 정의합니다.

#정의 _APS_다음_명령_값 40002

#정의 _APS_다음_제어_값 1001

#APS_다음_동기화_값 101을 정의합니다.

#끝

#끝

057_POEPOEM.rc리소스 스크립트 파일에는 4가지 유형의 리소스가 포함되어 있습니다.

1 . 아이콘 리소스:

// 아이콘

//

IDI_ICON1 ICON "D:\code\windows5.0\A 매일

연습\057_POEPOEM\057_POEPOEM\icon1.ico"

2 . 마우스 포인터 비트맵 리소스:

// 커서

//

IDC_CURSOR1 커서 "cursor1.cur"

3 . 문자열 리소스 테이블:

// 문자열 테이블

//

스트링테이블

시작하다

IDS_APPNAME "PoePoem"

IDS_CAPTION """Annabel Lee"" by Edgar Allan Poe"

IDS_ERRMSG "이 프로그램을 실행하려면 Windows NT가 필요합니다!"

4 . 맞춤 리소스:

// 텍스트

//

ANNABELLEE 텍스트 "POEPOEM.TXT"

작업 결과:

그림 9-9 문자열 리소스 테이블과 사용자 정의 리소스

 

요약하다

POEPOEM.RC 리소스 스크립트에서 사용자 정의 리소스는 TEXT 유형으로 지정되고 텍스트 이름은 "ANNABELLEE"입니다. ANNABELLEE TEXT POEPOEM.TXT

WndProc에서 WM_CREATE 메시지를 처리할 때 FindResource 및 LoadResource를 통해 리소스의 핸들을 얻습니다. LockResource는 리소스를 잠그고 작은 루틴은 파일의 후행 백슬래시( )를 0으로 바꿉니다. 이는 후속 WM_PAINT 메시지에서 DrawText 함수의 사용을 용이하게 하기 위한 것입니다.

[참고] 창 스크롤 막대 대신 하위 창 스크롤 막대 컨트롤을 사용합니다. 하위 창 스크롤 막대 컨트롤에는 자동 키보드 인터페이스가 있으므로 POEPOEM에서 WM_KEYDOWN 메시지를 처리할 필요가 없습니다.

POEPOEM은 또한 RESOURCE.H 헤더 파일에 ID가 정의된 세 개의 문자열을 사용합니다. 프로그램 시작 시 IDS_APPNAME 및 IDS_CAPTION 문자열은 LoadString에 의해 메모리에 로드됩니다.

LoadString(hlnstance, IDS_APPNAME, szAppName,

sizeof(szAppName) / sizeof(TCHAR));

LoadString(hlnstance, IDS_CAPTION, szCaption,

sizeof (szCaption) /sizeof (TCHAR));

[참고] 이 두 호출은 RegisterClass보다 우선합니다. 프로그램은 LoadStringA를 사용하여 IDS_APPNAME 및 IDS_ERRMSG 문자열을 로드하고 MessageBoxA를 사용하여 사용자 정의 메시지 상자를 표시합니다.

if (!RegisterClass(&wndclass))

{

LoadStringA(hInstance, IDS_APPNAME, (char *) szAppName,

sizeof(szAppName)) ;

LoadStringA(hInstance, IDS_ERRMSG, (char *) szErrMsg,

sizeof (szErrMsg)) ;

MessageBoxA(NULL, (char *) szErrMsg,

(char *) szAppName, MB_ICONERROR) ;

0을 반환합니다.

}

[참고] TCHAR 문자열 변수를 char 포인터로 강제 변환합니다.

AnsiNext는 16비트 Windows의 매크로 정의입니다. Win32는 대신 CharNext를 사용합니다. AnsiNext는 ansi 문자열만 처리할 수 있고 CharNext는 ansi 문자열과 유니코드 문자열을 모두 처리할 수 있습니다.

pText = AnsiNext(pText);

다음으로 교체:

pText = (LPCSTR)CharNext((LPCWSTR)pText);

POEPOEM에서 사용하는 모든 문자열은 리소스로 정의되어 있으므로 번역가가 프로그램을 영어가 아닌 버전으로 쉽게 변환할 수 있습니다.