2

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 EnumWindows 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 DrawIcon().

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 think is good to copy the icon in a temp buffer to get bytes but nothing works.

Any help would be appreciated.

EDIT:

@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 GetDIBits() 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 lpvBits? What's about Bitmap Size?

Marco Sanfilippo
  • 293
  • 3
  • 19

1 Answers1

4

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);
        CloseHandle(hFile);
    }
    GlobalUnlock(buffer);
}
// Cleanup
pStream->Release();
pPicture->Release();
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.

Community
  • 1
  • 1
Marco Sanfilippo
  • 293
  • 3
  • 19
  • Please add more information to your post. IF the link ever changes, your answer won't help anyone. – dckuehn Aug 26 '16 at 15:34