0

i have a Win32 API Application in Delphi 2007 with no form and would like to load a bitmap from a .res file. Been looking around for two day's and just can't seem to find anything on this subject so was time to post. :)

Assuming i need to add code to "WM_PAINT" message just not sure what to add. maybe could use GDI.

/Thanks.

EDIT:

function WndProc(hWin: HWnd; Msg, WParam, LParam: Longint): Longint; stdcall;
var
  hbmp: HBITMAP;
  ps: PAINTSTRUCT;
  DC, hdcMem: HDC;
  bmp: BITMAP;
  oldBitmap: HGDIOBJ;
begin
  case Msg of
    WM_CREATE:
    begin
      hbmp := LoadImage(HInstance, 'C:\test_img.bmp', IMAGE_BITMAP, 0, 0,    LR_LOADFROMFILE); // Never called H2077 Value assigned to 'hbmp' never used
      ShowMessage('Im Here'); // Called
      Result := 0;
      Exit;
    end;
    WM_PAINT:
    begin
      hbmp := LoadImage(HInstance, 'C:\test_img.bmp', IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); // Called
      DC := BeginPaint(hWin, ps);
      hdcMem := CreateCompatibleDC(DC);
      oldBitmap := SelectObject(hdcMem, hbmp);
      GetObject(hbmp, SizeOf(bmp), @bmp);
      BitBlt(DC, 0, 0, bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY);
      SelectObject(hdcMem, oldBitmap);
      DeleteDC(hdcMem);
      DeleteObject(hbmp);
      EndPaint(hWin, ps);
      Result := 0;
      Exit;
    end;
    WM_DESTROY:
    begin
      PostQuitMessage(0);
      Result := 0;
      Exit;
    end;
  end;
  Result := DefWindowProc(hWin, Msg, WParam, LParam);
end;

Am i right in thinking that WM_CREATE is the equivalent of Form1.OnCreate and WM_DESTROY is Form1.OnDestroy ect..

Se7en
  • 33
  • 1
  • 5
  • Can you explain more about what you are trying to achieve? You have no form, but you want to load a bitmap. You mention WM_PAINT so I assume you want to display it, rather than manipulate the bitmap. Is there a reason you can't just display another form on demand that has a TImage control? – Brian Lyttle Apr 22 '13 at 01:12
  • 1
    Wanted to try out some non-vcl programming, sorry my question was a bit short, didn't really know what else to add :) Thanks for your reply. – Se7en Apr 22 '13 at 02:18
  • Thanks. makes perfect sense now.. lol – Se7en Apr 22 '13 at 23:12

1 Answers1

1

Look at the TBitmap class in the Graphics unit. It has LoadFromResourceName() and LoadFromResourceID() methods.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Thanks for your reply. I have seen things like CreateCompatibleDC, CreateCompatibleBitmap can i not some how use these? Reply to your question: I did originally try these to test if my Resource ID was correct and nothing showed up on screen. – Se7en Apr 22 '13 at 02:19
  • 1
    @Ryan you can see the basics of painting an image directly over at http://stackoverflow.com/questions/1748470/how-to-draw-image-on-a-window. You need to have an understanding of how to use the Win32 API directly from Delphi before you actually do anything useful with that example. See http://delphi.about.com/od/windowsshellapi/a/apicourse.htm for some examples on getting started with Win32. – Brian Lyttle Apr 22 '13 at 18:26
  • 1
    @Ryan, those are Win32 API functions. `TBitmap` is a Delphi class that uses those API functions internally for you. – Remy Lebeau Apr 22 '13 at 19:18
  • @Remy, Oh right thank you. [@Brian], thanks for them links, rustled something up just 1 more question though if i may. WM_CREATE message when i assign hbm to LoadImage its never called but if i put it in the paint message everything works as normal :S any ideas please? Also if you could move that to an answer i can then accept :P or do i just upvote it? – Se7en Apr 22 '13 at 20:11
  • @Ryan: if your WM_CREATE handler is not being called, or is not calling `LoadImage()` correctly, then you are doing something wrong in your code. Update your question with your actual code, then someone can tell you what you are doing wrong and how to fix it. – Remy Lebeau Apr 22 '13 at 21:20
  • Done, its something todo with assigning hbmp to LoadImage in WM_CREATE as the ShowMessage is called as expected. But putting in the WM_PAINT message works fine. I was thinking maybe creating a new class handling my painting ect then just calling say .Create in WM_CREATE and Render() in WM_PAINT. Was just curious why Calling LoadImage there is complaining. – Se7en Apr 22 '13 at 22:41
  • As SerTac said, the compiler is likely optimizing out the call to `LoadImage()` in the `WM_CREATE` handler since `hbmp` is not being used anywhere before `Exit` is called. You can run your code through the IDE debugger to verify if that is actually happening or not. At the very least, add a call to `DeleteObject(hbmp)` in the `WM_CREATE` handler. That should avoid any optimization, as well as fix a resource leak. – Remy Lebeau Apr 22 '13 at 23:01
  • @Remy Thanks. If i call DeleteObject(hbmp) after LoadImage() in WM_CREATE wouldn't that stop my image from showing up at all as it would delete what i just created? or did you mean add DeleteObject(hbmp) in WM_DESTROY? – Se7en Apr 22 '13 at 23:14
  • I meant adding `DeleteObject()` to WM_CREATE, since that is where you are currently leaking an `HBITMAP`. No, that will not prevent the image from appearing. You are calling `LoadImage()` again every time `WM_PAINT` is called, but you are calling `DeleteObject()` each time so you are not leaking those `HBITMAP`s. You really should be loading the image only once in `WM_CREATE` and saving that `HBITMAP` somewhere, then re-using the same `HBITMAP` in `WM_PAINT`, and then final releasing that `HBITMAP` with `DeleteObject()` in `WM_DESTROY`. – Remy Lebeau Apr 23 '13 at 01:53
  • Yea, that is what i meant. When i use a global hbmp and remove the LoadImage() from WM_PAINT i wouldn't want a DeleteObject() inside WM_CREATE because it would remove my image. :) Thanks for everyone's help so far anyway, i will have a play around and read up the information you all have provided me in the Delphi documentation / msdn and get a better understanding of it all. – Se7en Apr 23 '13 at 03:26