2012-07-31 2 views
7
내가 메모리에서 RIFF 아카이브/용기로 설명 .ANI 형식으로 저장 애니메이션 커서를로드 할

에서 런타임에 애니메이션 커서를로드합니다. 지금까지 .ani 파일 구조를 파싱하고 개별 프레임을 일반적인 아이콘으로로드 할 수 있습니다. LookupIconIdFromDirectoryEx임시 파일에 메모리를 작성하지 않고 메모리

이러한 프레임의 실제 구성과 애니메이션 데이터 jiffy-rate 등)을 사용하여 Windows API에 항목이없는 것으로 보입니다. 주제에 관한 문서 또는 서면 지식은 메모리에서 애니메이션이 아닌 아이콘/커서를로드하는 것으로 제한됩니다. 같은 'Load an embedded animated Cursor from the Resource' 같은

비슷한 질문 임베디드 리소스에서 애니메이션 커서를로드하는 욕망을 표현한다. 그러나 나는 그 중 하나에서 실행 가능한 솔루션을 재현 할 수 없습니다. 부분적으로 Visual Studio 2008 & 2010의 리소스 컴파일러는 .ani (ico 및 cur 만) 파일을 지원하지 않기 때문에 원본 파일과는 반대로 바이트의 1 : 1 복사본을 만듭니다. cur 및 .ico 파일은 여러 자원으로 분해됩니다. 두 응답에 표시된 CreateIconFromResource에 대한 후속 호출은 RIFF 기반 파일 구조가 아닌 아이콘 아카이브의 단일 지시문의 아이콘/커서 데이터이므로 예상대로 작동하지 않습니다.

나는 내 목표를 추구하는 저를 도와 수 (메모리) 애니메이션 커서 또는 기타 관련 포인터의 구조에 관한 정보에 관심을 요약합니다.

답변

5

: 그런 다음에 커서를로드합니다.

삽입 가능한 리소스의 데이터와 파일에서 메모리로 읽은 데이터는 정확히 동일합니다. 따라서 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); 
} 
1

애니메이션 커서를 사용자 지정 리소스로 가져옵니다. "MyType"과 같은 텍스트 이름을 지정하십시오. MFC에서 지적 내가 나 임의의 메모리 주소에서 커서를로드 할 수있는 솔루션을 발견으로 임베디드 리소스에서 애니메이션 커서를로드 다시 평가 한 후

HCURSOR hCursor = LoadAnimatedCursor(IDR_MYTYPE1, _T("MyType")); 

/* ======================================================== */ 
HCURSOR LoadAnimatedCursor(UINT nID, LPCTSTR pszResouceType) 
{ 
    HCURSOR hCursor = NULL; 
    HINSTANCE hInstance = AfxGetInstanceHandle(); 
    if (hInstance) 
    { HRSRC hResource = FindResource(hInstance, MAKEINTRESOURCE(nID), pszResouceType); 
     DWORD dwResourceSize = SizeofResource(hInstance, hResource); 
     if (dwResourceSize>0) 
     { HGLOBAL hRsrcGlobal = LoadResource(hInstance, hResource); 
      if (hRsrcGlobal) 
      { LPBYTE pResource = (LPBYTE)LockResource(hRsrcGlobal); 
       if (pResource) 
       { hCursor = (HCURSOR)CreateIconFromResource(pResource, dwResourceSize, FALSE, 0x00030000); 
        UnlockResource(pResource); 
       } 
       FreeResource(hRsrcGlobal); 
      } 
     } 
    } 
    return hCursor; 
} 
+0

이것은 대부분의 사람들에게 확실한 해결책입니다. 그러나 그것은 아직도 내가 찾고있는 것에 대한 대안입니다. 이 질문의 근본적인 부분은 임의의 메모리에서로드 할 수 있다는 것입니다. –

관련 문제