How can I get the error message that occurs in the Draw method?

CDev-8220 470 Reputation points
2023-08-22T21:24:31.6166667+00:00

An error has occurred between BeginDraw, and EndDraw.

How do I get the error, or where it occurred.

I tried using EndDraw(&tag1, &tag2); and GetTags(&tag1, &tag2);, but I don't really know how to get the actual message from these.

Windows development | Windows API - Win32
Developer technologies | C++
Developer technologies | C++
A high-level, general-purpose programming language, created as an extension of the C programming language, that has object-oriented, generic, and functional features in addition to facilities for low-level memory manipulation.
{count} votes

Answer accepted by question author
  1. Castorix31 91,506 Reputation points
    2023-08-31T09:49:31.3933333+00:00

    I don't see why you cannot use the Direct2D Debug Layer, because it gives useful and detailed errors information

    But if you just want the message strings, you don't have to hardcode strings as they are in DLLs and you can call FormatMessage :

                WCHAR wsError[255] = L"", wsErrorMessage[255] = L"";
                // Test random errors
                //int nError = D2DERR_RECREATE_TARGET;
                int nError = D2DERR_UNSUPPORTED_VERSION;           
                GetErrorMessage(nError, NULL, wsErrorMessage);
                wsprintf(wsError, L"Error : %s\n", wsErrorMessage);
                MessageBox(NULL, wsError, L"Error", MB_OK | MB_ICONSTOP);
    

    with :

    void GetErrorMessage(DWORD nError, HMODULE hModule, __out_opt LPWSTR wszMessage)
    {
        LPVOID lpMsgBuf = NULL;
        DWORD nFlags = FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;
        if (hModule)
            nFlags |= FORMAT_MESSAGE_FROM_HMODULE;
        FormatMessage(nFlags, hModule,
            (HRESULT_FACILITY(nError) == FACILITY_WIN32) ? HRESULT_CODE(nError) : nError,
            MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
            (LPWSTR)&lpMsgBuf, 0, NULL);
        if (lpMsgBuf != NULL)
        {
            wsprintf(wszMessage, TEXT("%s"), (LPWSTR)lpMsgBuf);
            LocalFree(lpMsgBuf);
        }
    }
    

2 additional answers

Sort by: Most helpful
  1. Jeanine Zhang-MSFT 11,356 Reputation points Microsoft External Staff
    2023-08-28T02:37:19.08+00:00

    Hello,

    Welcome to Microsoft Q&A!

    I tried using EndDraw(&tag1, &tag2); and GetTags(&tag1, &tag2);, Do you mean ID2D1RenderTarget::BeginDraw? Not necessarily.

    What do you mean "Not necessarily"? Could you please tell us what are the EndDraw(&tag1, &tag2); and GetTags(&tag1, &tag2);?

    As far as I'm concerned, the Draw method in different interfaces has different ways to get the error message. If you want to get the error message that occurs in the Diretc2D, I also suggest you could try to use Direct2D Debug Layer

    UPDATE:

    So to get the error, we can set a breakpoint, on if (SUCCEEDED(hr)) {}, and take a peek at the message, in the console, or make our own little error message reporter.

    Thank you.

    Jeanine


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


  2. CDev-8220 470 Reputation points
    2023-08-30T11:32:49.2966667+00:00
    // Error Reporter
    
    const string errDesc[47]{
    	"The number is invalid",
    	"You can't draw with a bitmap that is currently bound as the target bitmap",
    	"You can't draw with a bitmap that has the D2D1_BITMAP_OPTIONS_CANNOT_DRAW option",
    	"A cycle occurred in the graph",
    	"The display format to render is not supported by the hardware device",
    	"A valid display state could not be determined",
    	"The class ID of the specified effect is not registered by the operating system",
    	"The requested size is larger than the guaranteed supported texture size",
    	"The brush types are incompatible for the call",
    	"The supplied buffer is too small to accommodate the data",
    	"The Direct3D device doesn't have sufficient capabilities to perform the requested action",
    	"You can't render the graph with the context's current tiling settings",
    	"The application should close this instance of Direct2D and restart it as a new process",
    	"A call to this method is invalid",
    	"A configuration error occurred in the graph",
    	"An internal configuration error occurred in the graph",
    	"The specified property doesn't exist",
    	"You can't set the image as a target because it is either an effect or a bitmap that ...",
    	"The application attempted to reuse a layer resource that has not yet been popped off the stack",
    	"The requested DX surface size exceeds the maximum texture size",
    	"There is no hardware rendering device available for this operation",
    	"The specified sub-property doesn't exist",
    	"The object has not yet been initialized",
    	"The operation failed because the original target isn't currently bound as a target",
    	"The operation can't complete while you have outstanding references to the target bitmap",
    	"The application attempted to pop a layer off the stack when a clip was at the top, or ...",
    	"This error occurs during print control creation (ID2D1Device::CreatePrintControl) to ...",
    	"The application called ID2D1PrintControl::AddPage or ID2D1PrintControl::Close after the ...",
    	"The application did not pop all clips and layers off the stack, or it attempted to pop too...",
    	"A presentation error has occurred that may be recoverable. The caller needs to re-create ...",
    	"The requested operation cannot be performed until all layers and clips have been popped ...",
    	"The geometry scanner failed to process the data",
    	"Direct2D could not access the screen",
    	"Shader compilation failed",
    	"The render target is not compatible with GDI",
    	"A text client drawing effect object is of the wrong type",
    	"An application is holding a reference to the IDWriteTextRenderer interface after the ...",
    	"Shader construction failed because it was too complex",
    	"An effect attempted to use a transform with too many inputs",
    	"The requested operation is not supported",
    	"The pixel format is not supported",
    	"The requested Direct2D version is not supported",
    	"An unknown Win32 failure occurred",
    	"Objects used together were not all created from the same factory instance",
    	"The resource used was created by a render target in a different resource domain",
    	"The object was not in the correct state to process the method",
    	"The supplied vector is zero"
    };
    const HRESULT hrErr[47]{
    	D2DERR_BAD_NUMBER,
    	D2DERR_BITMAP_BOUND_AS_TARGET,
    	D2DERR_BITMAP_CANNOT_DRAW,
    	D2DERR_CYCLIC_GRAPH,
    	D2DERR_DISPLAY_FORMAT_NOT_SUPPORTED,
    	D2DERR_DISPLAY_STATE_INVALID,
    	D2DERR_EFFECT_IS_NOT_REGISTERED,
    	D2DERR_EXCEEDS_MAX_BITMAP_SIZE,
    	D2DERR_INCOMPATIBLE_BRUSH_TYPES,
    	D2DERR_INSUFFICIENT_BUFFER,
    	D2DERR_INSUFFICIENT_DEVICE_CAPABILITIES,
    	D2DERR_INTERMEDIATE_TOO_LARGE,
    	D2DERR_INTERNAL_ERROR,
    	D2DERR_INVALID_CALL,
    	D2DERR_INVALID_GRAPH_CONFIGURATION,
    	D2DERR_INVALID_INTERNAL_GRAPH_CONFIGURATION,
    	D2DERR_INVALID_PROPERTY,
    	D2DERR_INVALID_TARGET,
    	D2DERR_LAYER_ALREADY_IN_USE,
    	D2DERR_MAX_TEXTURE_SIZE_EXCEEDED,
    	D2DERR_NO_HARDWARE_DEVICE,
    	D2DERR_NO_SUBPROPERTIES,
    	D2DERR_NOT_INITIALIZED,
    	D2DERR_ORIGINAL_TARGET_NOT_BOUND,
    	D2DERR_OUTSTANDING_BITMAP_REFERENCES,
    	D2DERR_POP_CALL_DID_NOT_MATCH_PUSH,
    	D2DERR_PRINT_FORMAT_NOT_SUPPORTED,
    	D2DERR_PRINT_JOB_CLOSED,
    	D2DERR_PUSH_POP_UNBALANCED,
    	D2DERR_RECREATE_TARGET,
    	D2DERR_RENDER_TARGET_HAS_LAYER_OR_CLIPRECT,
    	D2DERR_SCANNER_FAILED,
    	D2DERR_SCREEN_ACCESS_DENIED,
    	D2DERR_SHADER_COMPILE_FAILED,
    	D2DERR_TARGET_NOT_GDI_COMPATIBLE,
    	D2DERR_TEXT_EFFECT_IS_WRONG_TYPE,
    	D2DERR_TEXT_RENDERER_NOT_RELEASED,
    	D2DERR_TOO_MANY_SHADER_ELEMENTS,
    	D2DERR_TOO_MANY_TRANSFORM_INPUTS,
    	D2DERR_UNSUPPORTED_OPERATION,
    	D2DERR_UNSUPPORTED_PIXEL_FORMAT,
    	D2DERR_UNSUPPORTED_VERSION,
    	D2DERR_WIN32_ERROR,
    	D2DERR_WRONG_FACTORY,
    	D2DERR_WRONG_RESOURCE_DOMAIN,
    	D2DERR_WRONG_STATE,
    	D2DERR_ZERO_VECTOR
    };
    
    void showErr(HWND hwnd, HRESULT error, string ev) {
    	
    	for (int e = 0; e < 47; e++) {
    		if (error == hrErr[e]) {
    			string errStr = "ERROR : " + errDesc[e];
    
    			//.........Convert your strings here. I did this on the fly, so sorry aout the mess :D
    			//MessageBox(hwnd, [err], [event], MB_OK | MB_ICONEXCLAMATION);
    
    		}
    	}
    }
    
    string event = "drawingg ...";
    hr = deviceContext->EndDraw();
    if (SUCCEEDED(hr)) {}
    else { showErr(m_hwnd, hr, event); }
    
    
    0 comments No comments

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.