: 그런 다음에 커서를로드합니다.
삽입 가능한 리소스의 데이터와 파일에서 메모리로 읽은 데이터는 정확히 동일합니다. 따라서 CreateIconFromResource 은이 정상적인 일반 메모리에서도 작동해야 함을 나타냅니다. 그러나 한 가지 근본적인 차이점이 있습니다. 임베드 가능한 자원의 메모리는 실행 파일의 특수 섹션에 있으며, 가장 가까운 4096 바이트 경계로 패딩되는 경우가 많습니다. 런타임에 할당 된 메모리에는 가비지 값이 들어 있습니다. 이제
단순히 제로 채워진 바이트의 보호 대역을 할당하여이 작업을 악용있는 솔루션입니다. 내 자신의 테스트 케이스에서 나는 8이 리프 컨테이너에있는 덩어리의 크기 일 수도있는 최소값이라는 것을 발견했다. 일치? 내가 생각하기에 이것은 버그이며 알고리즘은 dll/실행 파일 내의 정렬 제한 때문에 임베드 가능한 리소스에서 작동합니다.
const int guardbandSize = 8;
FILE* fs = fopen("action.ani", "rb");
fseek(fs, 0,SEEK_END); int dwSize = ftell(fs); fseek(fs, 0,SEEK_SET);
char* memory = new char[dwSize + guardbandSize];
fread(memory, 1, dwSize, fs); memset(memory + dwSize, 0, guardbandSize);
fclose(fs);
cursor = (HCURSOR)CreateIconFromResource((PBYTE)memory,dwSize,FALSE,0x00030000);
delete memory;
다음은 애니메이션 커서를로드하는 다양한 방법에 대한 개요입니다.
#include <Windows.h>
#include <stdio.h>
#include "resource2.h"
void* hWnd;
bool visible = true;
bool running = true;
LRESULT CALLBACK WndProcInternal( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) ;
HCURSOR cursor = 0;
void main()
{
//Setup configuration
const int Width = 640, Height = 480;
const int Method = 4;
//Setup window class
WNDCLASS wcd;
wcd.style = CS_PARENTDC | CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wcd.lpfnWndProc = (WNDPROC)WndProcInternal;
wcd.cbClsExtra = 0;
wcd.cbWndExtra = 0;
wcd.hInstance = GetModuleHandle(NULL);
wcd.hIcon = LoadIcon(NULL, IDI_WINLOGO);
wcd.hCursor = LoadCursor(NULL, IDC_ARROW);
wcd.hbrBackground = (HBRUSH)COLOR_BACKGROUND;
wcd.lpszMenuName = NULL;
wcd.lpszClassName = TEXT("AnimatedIcon");
//Register the window class
if(!RegisterClass(&wcd))
{
MessageBox(NULL, TEXT("Window Registration Failed!"), TEXT("Error!"),MB_ICONEXCLAMATION | MB_OK);
FatalExit(-1);
}
//Create a window
if (!(hWnd=CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("AnimatedIcon"), TEXT("AnimatedIcon"),
WS_VISIBLE | WS_CAPTION | WS_MINIMIZEBOX | WS_THICKFRAME | WS_MAXIMIZEBOX | WS_SYSMENU,
0, 0, Width, Height, NULL, NULL, NULL, NULL)))
{
MessageBoxA(NULL,"Window Creation Error.","ERROR",MB_OK|MB_ICONEXCLAMATION);
FatalExit(-1);
}
if(Method == 1)
{
//Method 1: Load cursor directly from a file
cursor = LoadCursorFromFileA("action.ani");
}
if(Method == 2)
{
//Method 2: Load cursor from an resource section in the executable.
cursor = LoadCursor(0, MAKEINTRESOURCE(IDR_ANICURSORS1));
}
if(Method == 3)
{
//Method 3: Manually locate the resource section in the executable & create the cursor from the memory.
HINSTANCE hInst=GetModuleHandle(0);
HRSRC hRes=FindResourceA(hInst,MAKEINTRESOURCEA(IDR_ANICURSORS1),"ANICURSORS");
DWORD dwSize=SizeofResource(hInst,hRes);
HGLOBAL hGlob=LoadResource(hInst,hRes);
LPBYTE pBytes=(LPBYTE)LockResource(hGlob);
cursor = (HCURSOR)CreateIconFromResource(pBytes,dwSize,FALSE,0x00030000);
}
if(Method == 4)
{
//Method 4: Load the cursor from a file into memory & create the cursor from the memory.
const int guardbandSize = 8;
FILE* fs = fopen("action.ani", "rb");
fseek(fs, 0,SEEK_END); int dwSize = ftell(fs); fseek(fs, 0,SEEK_SET);
char* memory = new char[dwSize + guardbandSize];
fread(memory, 1, dwSize, fs); memset(memory + dwSize, 0, guardbandSize);
fclose(fs);
cursor = (HCURSOR)CreateIconFromResource((PBYTE)memory,dwSize,FALSE,0x00030000);
delete memory;
}
//Set the cursor for the window and display it.
SetClassLong((HWND)hWnd, GCL_HCURSOR, (LONG)cursor);
while (running)
{
MSG wmsg;
if (PeekMessage(&wmsg, (HWND)hWnd, 0, 0, PM_REMOVE))
{
TranslateMessage(&wmsg);
DispatchMessage(&wmsg);
}
}
}
LRESULT CALLBACK WndProcInternal( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if(uMsg == WM_DESTROY)
{
PostQuitMessage(1);
running = false;
}
return (long)DefWindowProc((HWND)hWnd,uMsg,(WPARAM)wParam,(LPARAM)lParam);
}
이것은 대부분의 사람들에게 확실한 해결책입니다. 그러나 그것은 아직도 내가 찾고있는 것에 대한 대안입니다. 이 질문의 근본적인 부분은 임의의 메모리에서로드 할 수 있다는 것입니다. –