2012-07-31 14 views
7

से रनटाइम पर एनिमेटेड कर्सर लोड करें। मैं एक अस्थायी फ़ाइल में स्मृति लिखने के बिना स्मृति से आरआईएफएफ संग्रह/कंटेनर के रूप में वर्णित एक एनिमेटेड कर्सर लोड करना चाहता हूं। इस प्रकार अब तक मैं .ani फ़ाइल संरचना पार्स और CreateIconFromResourceExLookupIconIdFromDirectoryExमेमोरी

समस्याओं कि मुश्किल सबूत इन फ्रेम और एनीमेशन डेटा की वास्तविक संरचना है में से एक की सहायता से एक सामान्य चिह्न के रूप में व्यक्तिगत फ्रेम लोड (करने में सक्षम हूँ jiffy-rate आदि) क्योंकि ऐसा करने के लिए विंडोज एपीआई में कोई प्रविष्टि नहीं है। इस विषय पर दस्तावेज़ीकरण या लिखित ज्ञान स्मृति से गैर-एनिमेटेड आइकन/कर्सर लोड करने तक ही सीमित है।

'Load an embedded animated Cursor from the Resource' जैसे समान प्रश्न एक एम्बेडेड संसाधन से एनिमेटेड कर्सर लोड करने की इच्छा व्यक्त करते हैं। हालांकि मैं उस से एक व्यावहारिक समाधान पुन: उत्पन्न करने में सक्षम नहीं हूं। आंशिक रूप से क्योंकि विजुअल स्टूडियो 2008 & 2010 में संसाधन कंपाइलर .ani (केवल ico और cur) फ़ाइलों का समर्थन नहीं करता है और इसके लिए इसे एम्बेड करने के लिए बाइट्स की 1: 1 प्रतिलिपि में परिणाम होता है क्योंकि वे मूल फ़ाइल में थे। cur और .ico फ़ाइलें जो एकाधिक संसाधनों में विघटित हो जाती हैं। दोनों उत्तरों में दिखाए गए CreateIconFromResource के बाद की कॉल काम नहीं करती है क्योंकि वह डेटा जो आइकन की अपेक्षा करता है वह आइकन संग्रह में एक ही निर्देश का आइकन/कर्सर डेटा है और आरआईएफएफ-आधारित फ़ाइल संरचना नहीं है।

संक्षेप में मुझे एनिमेटेड कर्सर (स्मृति में) या अन्यथा प्रासंगिक पॉइंटर्स की संरचनाओं के बारे में किसी भी जानकारी में रूचि है जो मेरे लक्ष्य को आगे बढ़ाने में मेरी सहायता कर सकता है।

उत्तर

5

: फिर साथ कर्सर लोड।

एक एम्बेड करने योग्य संसाधन और डेटा से मेमोरी में पढ़ने वाले डेटा से डेटा बिल्कुल समान है। इसके लिए यह सुझाव देता है कि CreateIconFromResource सामान्य नियमित स्मृति पर भी काम करना चाहिए। हालांकि एक मौलिक अंतर है। निष्पादन योग्य संसाधनों की स्मृति निष्पादन योग्य विशेष वर्गों में रहती है जो अक्सर निकटतम 4096-बाइट सीमा तक पैड की जाती हैं। रनटाइम पर आवंटित मेमोरी में कचरा मूल्य होता है।

अब जो समाधान मैंने पाया है वह शून्य-भरे बाइट्स के गार्ड-बैंड को आवंटित करके इसका शोषण करता है। अपने स्वयं के परीक्षण मामलों में मैंने पाया है कि 8 न्यूनतम है जो रिफ कंटेनर में एक हिस्से का आकार भी होता है। संयोग? मुझे संदेह है कि यह एक बग है और एल्गोरिदम डीएल/निष्पादन योग्य के भीतर संरेखण प्रतिबंधों के कारण एम्बेड करने योग्य संसाधनों के लिए काम करता है।

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

अपने एनिमेटेड कर्सर को कस्टम संसाधन के रूप में आयात करें। इसे एक टेक्स्ट नाम दें, जैसे "माईटाइप"। पुनः आकलन करने के रूप में 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

यह एक समाधान है जो मुझे यकीन है कि ज्यादातर लोगों के लिए काम करता है। हालांकि यह अभी भी एक विकल्प है जिसे मैं वास्तव में ढूंढ रहा हूं। इस सवाल का एक मौलिक हिस्सा इसे मनमाने ढंग से स्मृति से लोड करने की क्षमता है। –