Search code examples
c++winapigdi+watermark

GDI+ DrawString doesnt draw on PDF and PNG Format


I want to draw water mark on some documents like JPG, DOCX, PNG and PDF when printing. for this purpose, I Hook EndPage() function and use GDI+ DrawString to Draw Some Text. My code works well for Docx and JPG but the when I print PDF or PNG the water mark is not drawn. Any body know why this happened? this my code:

I get water mark info trough RPC I check RPC the info received correctly in all formats

    int EndPageHook::hookFunction(HDC hdc)
{


    //Intialize GdiplusStartupInput and Graphics
    Gdiplus::GdiplusStartupInput gdiplusStartupInput;
    Gdiplus::GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);
    Graphics graphic_Obj(hdc);

    //Get Watermark Information Throught RPC
    WatermarkParameters = WaterMarkRPCClient::GetWaterMarkInfo(status, printInfo);
    
    //Get Watermark Information and set in local variables
    string s = std::to_string(WatermarkParameters.transparency);
    s = std::to_string(WatermarkParameters.positions);
    s = std::to_string(WatermarkParameters.font);

    //Concatenation Text + User + Ip + Date 
    wcsncat_s(finalsenetce, WatermarkParameters._text, 512);

    if (WatermarkParameters.Has_UserName)
    {
        wcsncat_s(finalsenetce, WatermarkParameters._username, 256);
    }
    if (WatermarkParameters.Has_Client)
    {
        wcsncat_s(finalsenetce, WatermarkParameters._client, 256);
    }
    if (WatermarkParameters.Has_Date)
    {
        wcsncat_s(finalsenetce, WatermarkParameters._date, 256);
    }
    {
    
        //Set watermark position
        StringAlignment WMLocation{};
        StringFormat stringFormat;
        switch (WatermarkParameters.positions)
        {
        case 1:
            stringFormat.SetAlignment(StringAlignment::StringAlignmentNear);
            stringFormat.SetLineAlignment(StringAlignment::StringAlignmentNear);
            break;
        case 2:
            stringFormat.SetAlignment(StringAlignment::StringAlignmentCenter);
            stringFormat.SetLineAlignment(StringAlignment::StringAlignmentCenter);
            break;
        case 3:
            stringFormat.SetAlignment(StringAlignment::StringAlignmentFar);
            stringFormat.SetLineAlignment(StringAlignment::StringAlignmentFar);
            break;
        default:
            stringFormat.SetAlignment(StringAlignment::StringAlignmentCenter);
            stringFormat.SetLineAlignment(StringAlignment::StringAlignmentCenter);
            break;
        }


        
        // Claculate Page Size
        double WidthsPixels = GetDeviceCaps(hdc, VERTRES); 
        double   HeightsPixels = GetDeviceCaps(hdc, HORZRES);
        double WidthsPixelsPerInch = GetDeviceCaps(hdc, LOGPIXELSX);
        double   HeightsPixelsPeInch = GetDeviceCaps(hdc, LOGPIXELSY);
        ////----------------------------------------------------------------------------------------------------------------    

        Gdiplus::FontFamily nameFontFamily(L"Arial");
        Gdiplus::Font         font(&nameFontFamily, WatermarkParameters.font, Gdiplus::FontStyleBold, Gdiplus::UnitPoint);
        Gdiplus::RectF        rectF(0, 0, 20, 20);
        Gdiplus::SolidBrush   solidBrush(Gdiplus::Color(WatermarkParameters.transparency, 250, 0, 250));

        rectF.Width = (HeightsPixels / HeightsPixelsPeInch)* Screendpi;
        rectF.Height = (WidthsPixels / WidthsPixelsPerInch)* Screendpi;
        


        graphic_Obj.DrawString(finalsenetce, -1, &font, rectF, &stringFormat, &solidBrush);
    }
    GdiplusShutdown(m_gdiplusToken); 

    return getOriginalFunction()(hdc);```
}

Solution

  • I finally find the solution... First I must return 1; instead of return getOriginalFunction()(hdc);. Second I must add Scope { before Graphics graphic_Obj(hdc); and close it after GdiplusShutdown(m_gdiplusToken); here is the correct code

        int EndPageHook::hookFunction(HDC hdc)
    {
        //Intialize GdiplusStartupInput and Graphics
        Gdiplus::GdiplusStartupInput gdiplusStartupInput;
        Gdiplus::GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);
        {
            Graphics graphic_Obj(hdc);
    
            //Get Watermark Information Throught RPC
            WatermarkParameters = WaterMarkRPCClient::GetWaterMarkInfo(status, printInfo);
    
    
    
            //Get Watermark Information and set in local variables
            string s = std::to_string(WatermarkParameters.transparency);
            s = std::to_string(WatermarkParameters.positions);
            s = std::to_string(WatermarkParameters.font);
    
            //Concatenation Text + User + Ip + Date 
            wcsncat_s(finalsenetce, WatermarkParameters._text, 512);
    
            if (WatermarkParameters.Has_UserName)
            {
                wcsncat_s(finalsenetce, WatermarkParameters._username, 256);
            }
            if (WatermarkParameters.Has_Client)
            {
                wcsncat_s(finalsenetce, WatermarkParameters._client, 256);
            }
            if (WatermarkParameters.Has_Date)
            {
                wcsncat_s(finalsenetce, WatermarkParameters._date, 256);
            }
    
    
            //Set watermark position
            StringAlignment WMLocation{};
            StringFormat stringFormat;
            switch (WatermarkParameters.positions)
            {
            case 1:
                stringFormat.SetAlignment(StringAlignment::StringAlignmentNear);
                stringFormat.SetLineAlignment(StringAlignment::StringAlignmentNear);
                break;
            case 2:
                stringFormat.SetAlignment(StringAlignment::StringAlignmentCenter);
                stringFormat.SetLineAlignment(StringAlignment::StringAlignmentCenter);
                break;
            case 3:
                stringFormat.SetAlignment(StringAlignment::StringAlignmentFar);
                stringFormat.SetLineAlignment(StringAlignment::StringAlignmentFar);
                break;
            default:
                stringFormat.SetAlignment(StringAlignment::StringAlignmentCenter);
                stringFormat.SetLineAlignment(StringAlignment::StringAlignmentCenter);
                break;
            }
    
    
    
            // Claculate Page Size
            double WidthsPixels = GetDeviceCaps(hdc, VERTRES); // Get Device WIDTH
            double   HeightsPixels = GetDeviceCaps(hdc, HORZRES);//Get Device HEIGHT
            double WidthsPixelsPerInch = GetDeviceCaps(hdc, LOGPIXELSX);// Get Document  Pixel Per Inch in WIDTH of Screen
            double   HeightsPixelsPeInch = GetDeviceCaps(hdc, LOGPIXELSY);// Get Document Pixel Per Inch in HEIGHT of Screen
            ////----------------------------------------------------------------------------------------------------------------    
    
            Gdiplus::FontFamily nameFontFamily(L"Arial");
            Gdiplus::Font         font(&nameFontFamily, WatermarkParameters.font, Gdiplus::FontStyleBold, Gdiplus::UnitPoint);
            Gdiplus::RectF        rectF(0, 0, 200, 200);
            Gdiplus::SolidBrush   solidBrush(Gdiplus::Color(WatermarkParameters.transparency, 250, 0, 250));
    
    
            rectF.Width = (HeightsPixels / HeightsPixelsPeInch)* Screendpi;
            rectF.Height = (WidthsPixels / WidthsPixelsPerInch)* Screendpi;
    
            graphic_Obj.DrawString(finalsenetce, -1, &font, rectF, &stringFormat, &solidBrush);
        }
        GdiplusShutdown(m_gdiplusToken);
    
        return 1;
    }