Marco Sanfilippo Marco Sanfilippo - 4 months ago 45
C++ Question

Get bytes/char* from hIcon/hBitmap

I'm working on a C/S application, Server in C++ and Client in C#, I need to send some information about current running processes and related icon.
I get icon file thanks to

with this code inside the callback...

// Get the window icon
HICON hIcon = (HICON)(::SendMessageW(hWnd, WM_GETICON, ICON_SMALL, 0));
if (hIcon == 0) {
// Alternative method. Get from the window class
hIcon = reinterpret_cast<HICON>(::GetClassLongPtrW(hWnd, GCLP_HICONSM));
// Alternative: get the first icon from the main module
if (hIcon == 0) {
hIcon = ::LoadIcon(GetModuleHandleW(0), MAKEINTRESOURCE(0));
// Alternative method. Use OS default icon
if (hIcon == 0) {
hIcon = ::LoadIcon(0, IDI_APPLICATION);

OK, now I have the Icon and I can "print" it (simply for check) with

My question is: How to get bytes starting from this?
I need a buffer to send this data to my Client and CONVERT the same data to display icon in a list (icon + process_name). So, I need to get bytes of this icon/hIcon (or bitmap/hBitmap, etc.)
(Of course I need help for server side.)

I found something with
but doesn't work. I think is good to copy the icon in a temp buffer to get bytes but nothing works.

Any help would be appreciated.


@DavidHeffernan thank you for reply. I found this: Converting-DDB-to-DIB through StackOverflow's past questions (sorry if is bad to post external links).
Now, with
I have in the fifth param the
LPVOID lpvBits
, that is "A pointer to a buffer to receive the bitmap data msdn - GetDIBits()"
Now, How Should I send from
? What's about Bitmap Size?


I've found something on MSDN and StackOverflow and it helped me: link;

#include "stdafx.h"
#include <windows.h>
#include <olectl.h>
#pragma comment(lib, "oleaut32.lib")

HRESULT SaveIcon(HICON hIcon, const wchar_t* path) {
// Create the IPicture intrface
PICTDESC desc = { sizeof(PICTDESC) };
desc.picType = PICTYPE_ICON;
desc.icon.hicon = hIcon;
IPicture* pPicture = 0;
HRESULT hr = OleCreatePictureIndirect(&desc, IID_IPicture, FALSE, (void**)&pPicture);
if (FAILED(hr)) return hr;

// Create a stream and save the image
IStream* pStream = 0;
CreateStreamOnHGlobal(0, TRUE, &pStream);
LONG cbSize = 0;
hr = pPicture->SaveAsFile(pStream, TRUE, &cbSize);

// Write the stream content to the file
if (!FAILED(hr)) {
    HGLOBAL hBuf = 0;
    GetHGlobalFromStream(pStream, &hBuf);
    void* buffer = GlobalLock(hBuf);
    HANDLE hFile = CreateFile(path, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0);
    if (!hFile) hr = HRESULT_FROM_WIN32(GetLastError());
    else {
        DWORD written = 0;
        WriteFile(hFile, buffer, cbSize, &written, 0);
// Cleanup
return hr;

int _tmain(int argc, _TCHAR* argv[])
    HICON hIcon = (HICON)LoadImage(0,         L"c:\\windows\\system32\\perfcentercpl.ico", IMAGE_ICON, 32, 32,     LR_LOADFROMFILE);
    if (!hIcon) return GetLastError();
    HRESULT hr = SaveIcon(hIcon, L"c:\\temp\\test.ico");
    return hr;

Thanks to SaveIcon() I can save it and after, when needed, I can open it as binary file and send it via socket.