{"id":1101,"date":"2011-08-04T18:28:18","date_gmt":"2011-08-04T16:28:18","guid":{"rendered":"http:\/\/mariusbancila.ro\/blog\/?p=1101"},"modified":"2019-07-02T16:32:18","modified_gmt":"2019-07-02T14:32:18","slug":"display-images-as-you-type-in-cpp","status":"publish","type":"post","link":"https:\/\/mariusbancila.ro\/blog\/2011\/08\/04\/display-images-as-you-type-in-cpp\/","title":{"rendered":"Display images as you type in C++"},"content":{"rendered":"<p>There was a <a href=\"http:\/\/stackoverflow.com\/questions\/6924597\/how-do-i-link-c-visual-studio-2010-to-an-image-outputting-event-listener\">question on Stackoverflow<\/a> about a C++ project displaying an image as you type. Here is the original question:<\/p>\n<blockquote><p>I am writing a very simple program in C++ that listens to keyboard input, but what I want to output is much more difficult than I expected. For every key I press, I want an image (specific to the key) to appear on the screen. For example, let&#8217;s say if I press the &#8220;O&#8221; key, an image of Earth appears on my screen.<\/p><\/blockquote>\n<p>It sounded like a fun exercise to do in C++ using Windows API. So here is my quick answer, a simple solution to the problem.<\/p>\n<p>I wanted to display three different images, an earth, a moon and a sun, when the user types E, M or S in the window. The images should use transparency, so I decided to use PNG files. Here is how the images look.<br \/>\n<img loading=\"lazy\" decoding=\"async\" alt=\"\" src=\"\/blog\/wp-content\/uploads\/2011\/08\/earth.png\" title=\"earth\" class=\"alignnone\" width=\"128\" height=\"128\" \/><br \/>\n<img loading=\"lazy\" decoding=\"async\" alt=\"\" src=\"\/blog\/wp-content\/uploads\/2011\/08\/moon.png\" title=\"moon\" class=\"alignnone\" width=\"128\" height=\"128\" \/><br \/>\n<img loading=\"lazy\" decoding=\"async\" alt=\"\" src=\"\/blog\/wp-content\/uploads\/2011\/08\/sun.png\" title=\"sun\" class=\"alignnone\" width=\"128\" height=\"128\" \/><\/p>\n<p>A good option for loading PNG files is using <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ee719654.aspx\">Windows Imaging Component<\/a>. The point would be to add the PNG files to the project resources, then use WIC to load them and create an HBITMAP that would be used later to display the image. Bradley Grainger had just the right code on his <a href=\"http:\/\/code.logos.com\/blog\/2008\/09\/displaying_a_splash_screen_with_c_part_i.html\">blog<\/a>. This is how it looks, except that I made some slight modifications to LoadImageFromResources (called LoadSplashImage on his blog).<\/p>\n<pre name=\"code\" class=\"cpp\">\r\nIStream* CreateStreamOnResource(LPCTSTR lpName, LPCTSTR lpType)\r\n{\r\n   IStream * ipStream = NULL;\r\n\r\n   HRSRC hrsrc = FindResource(NULL, lpName, lpType);\r\n   if (hrsrc == NULL)\r\n      goto Return;\r\n\r\n   DWORD dwResourceSize = SizeofResource(NULL, hrsrc);\r\n   HGLOBAL hglbImage = LoadResource(NULL, hrsrc);\r\n   if (hglbImage == NULL)\r\n      goto Return;\r\n\r\n   LPVOID pvSourceResourceData = LockResource(hglbImage);\r\n   if (pvSourceResourceData == NULL)\r\n      goto Return;\r\n\r\n   HGLOBAL hgblResourceData = GlobalAlloc(GMEM_MOVEABLE, dwResourceSize);\r\n   if (hgblResourceData == NULL)\r\n      goto Return;\r\n\r\n   LPVOID pvResourceData = GlobalLock(hgblResourceData);\r\n\r\n   if (pvResourceData == NULL)\r\n      goto FreeData;\r\n\r\n   CopyMemory(pvResourceData, pvSourceResourceData, dwResourceSize);\r\n\r\n   GlobalUnlock(hgblResourceData);\r\n\r\n   if (SUCCEEDED(CreateStreamOnHGlobal(hgblResourceData, TRUE, &ipStream)))\r\n      goto Return;\r\n\r\nFreeData:\r\n   GlobalFree(hgblResourceData);\r\n\r\nReturn:\r\n   return ipStream;\r\n}\r\n\r\nIWICBitmapSource* LoadBitmapFromStream(IStream * ipImageStream)\r\n{\r\n   IWICBitmapSource* ipBitmap = NULL;\r\n\r\n   IWICBitmapDecoder* ipDecoder = NULL;\r\n   if (FAILED(CoCreateInstance(CLSID_WICPngDecoder, NULL, CLSCTX_INPROC_SERVER, \r\n                               __uuidof(ipDecoder), reinterpret_cast&lt;void**&gt;(&ipDecoder))))\r\n      goto Return;\r\n\r\n   if (FAILED(ipDecoder->Initialize(ipImageStream, WICDecodeMetadataCacheOnLoad)))\r\n      goto ReleaseDecoder;\r\n\r\n   UINT nFrameCount = 0;\r\n   if (FAILED(ipDecoder->GetFrameCount(&nFrameCount)) || nFrameCount != 1)\r\n      goto ReleaseDecoder;\r\n\r\n   IWICBitmapFrameDecode* ipFrame = NULL;\r\n   if (FAILED(ipDecoder->GetFrame(0, &ipFrame)))\r\n      goto ReleaseDecoder;\r\n\r\n   WICConvertBitmapSource(GUID_WICPixelFormat32bppPBGRA, ipFrame, &ipBitmap);\r\n   ipFrame->Release();\r\n\r\nReleaseDecoder:\r\n   ipDecoder->Release();\r\nReturn:\r\n   return ipBitmap;\r\n}\r\n\r\nHBITMAP CreateHBITMAP(IWICBitmapSource* ipBitmap)\r\n{\r\n   HBITMAP hbmp = NULL;\r\n\r\n   UINT width = 0;\r\n   UINT height = 0;\r\n   if (FAILED(ipBitmap->GetSize(&width, &height)) || width == 0 || height == 0)\r\n      goto Return;\r\n\r\n   BITMAPINFO bminfo;\r\n\r\n   ZeroMemory(&bminfo, sizeof(bminfo));\r\n   bminfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);\r\n   bminfo.bmiHeader.biWidth = width;\r\n   bminfo.bmiHeader.biHeight = -((LONG) height);\r\n   bminfo.bmiHeader.biPlanes = 1;\r\n   bminfo.bmiHeader.biBitCount = 32;\r\n   bminfo.bmiHeader.biCompression = BI_RGB;\r\n\r\n   void * pvImageBits = NULL;\r\n   HDC hdcScreen = GetDC(NULL);\r\n   hbmp = CreateDIBSection(hdcScreen, &bminfo, DIB_RGB_COLORS, &pvImageBits, NULL, 0);\r\n   ReleaseDC(NULL, hdcScreen);\r\n   if (hbmp == NULL)\r\n      goto Return;\r\n\r\n   const UINT cbStride = width * 4;\r\n   const UINT cbImage = cbStride * height;\r\n   if (FAILED(ipBitmap->CopyPixels(NULL, cbStride, cbImage, static_cast&lt;BYTE*>(pvImageBits))))\r\n   {\r\n      DeleteObject(hbmp);\r\n      hbmp = NULL;\r\n   }\r\n\r\nReturn:\r\n   return hbmp;\r\n}\r\n\r\nHBITMAP LoadImageFromResources(LPCTSTR lpName, LPCTSTR lpType)\r\n{\r\n   HBITMAP hbmpSplash = NULL;\r\n\r\n   IStream* ipImageStream = CreateStreamOnResource(lpName, lpType);\r\n   if (ipImageStream == NULL)\r\n      goto Return;\r\n\r\n   IWICBitmapSource* ipBitmap = LoadBitmapFromStream(ipImageStream);\r\n   if (ipBitmap == NULL)\r\n      goto ReleaseStream;\r\n\r\n   hbmpSplash = CreateHBITMAP(ipBitmap);\r\n   ipBitmap->Release();\r\n\r\nReleaseStream:\r\n   ipImageStream->Release();\r\n\r\nReturn:\r\n   return hbmpSplash;\r\n}\r\n<\/pre>\n<p>However for this to work the following are necessary:<\/p>\n<pre name=\"code\" class=\"cpp\">\r\n#include &lt;Objidl.h>\r\n#include &lt;Wincodec.h>\r\n\r\n#pragma comment (lib, \"windowscodecs.lib\")\r\n<\/pre>\n<p>Objidl.h is required for IStream, while Wincodec.h and windowscodecs.lib for WIC.<\/p>\n<p>I have created a Win32 Project, called TypePictures. The wizard generates the backbone for the app, but I&#8217;ll not talk about that part. Besides adding the functions listed above, I also added the following:<\/p>\n<pre name=\"code\" class=\"cpp\">\r\nHWND g_hPictureWnd = NULL;\r\nHBITMAP g_hbmp;\r\nUINT_PTR g_timer = 0;\r\nconst TCHAR c_szPictureClass[] = _T(\"myPictureWindow\");\r\n\r\nATOM RegisterPictureWindowClass(HINSTANCE hInstance);\r\nBOOL CreatePictureWindow(HINSTANCE hInstance, HWND hOwner);\r\nBOOL DestroyPictureWindow();\r\nBOOL SetPicture(HBITMAP hbmp);\r\nVOID CALLBACK PictureTimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime);\r\n<\/pre>\n<p>hPictureWnd is the handle to the window that displays the image, g_timer is a timer used for automatically closing the window after a desire interval, and g_hbmp is the handle to the current loaded image.<\/p>\n<p>RegisterPictureWindowClass registers the window class for the picture window. It uses the c_szPictureClass defined earlier for the class name.<\/p>\n<pre name=\"code\" class=\"cpp\">\r\nATOM RegisterPictureWindowClass(HINSTANCE hInstance)\r\n{\r\n   WNDCLASSEX wcex = {0};\r\n\r\n   wcex.cbSize = sizeof(WNDCLASSEX);\r\n\r\n   wcex.lpfnWndProc\t= DefWindowProc;\r\n   wcex.cbClsExtra\t= 0;\r\n   wcex.cbWndExtra\t= 0;\r\n   wcex.hInstance\t= hInstance;\r\n   wcex.hIcon\t\t= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_TYPEPICTURES));\r\n   wcex.hCursor\t\t= LoadCursor(NULL, IDC_ARROW);\r\n   wcex.hbrBackground\t= (HBRUSH)(COLOR_WINDOW+1);\r\n   wcex.lpszClassName\t= c_szPictureClass;\r\n   wcex.hIconSm\t\t= LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));\r\n\r\n   return RegisterClassEx(&wcex);\r\n}\r\n<\/pre>\n<p>This will be called in the main function before the call to InitInstance.<\/p>\n<pre name=\"code\" class=\"cpp\">\r\nRegisterPictureWindowClass(hInstance);\r\n<\/pre>\n<p>CreatePictureWindow is a function that creates the picture window. This will be a layered window that we&#8217;ll later update with <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms633556%28VS.85%29.aspx\">UpdateLayeredWindow<\/a> when displayined the picture.<\/p>\n<pre name=\"code\" class=\"cpp\">\r\nBOOL CreatePictureWindow(HINSTANCE hInstance, HWND hOwner)\r\n{\r\n   if(g_hPictureWnd != NULL)\r\n      return FALSE;\r\n\r\n   RECT rcwin;\r\n   GetWindowRect(hOwner, &rcwin);\r\n\r\n   g_hPictureWnd = ::CreateWindowEx(\r\n      WS_EX_LAYERED,\r\n      c_szPictureClass, \r\n      NULL, \r\n      WS_POPUP | WS_VISIBLE,\r\n      rcwin.right+1, rcwin.top, 128, 128, \r\n      hOwner, \r\n      NULL, \r\n      hInstance, \r\n      NULL);\r\n\r\n   return g_hPictureWnd != NULL;\r\n}\r\n<\/pre>\n<p>DestroyPictureWindow does what the name implies, it destroys the layered window that displays the picture.<\/p>\n<pre name=\"code\" class=\"cpp\">\r\nBOOL DestroyPictureWindow()\r\n{\r\n   if(g_hPictureWnd == NULL)\r\n      return FALSE;\r\n\r\n   BOOL ret = DestroyWindow(g_hPictureWnd);\r\n   g_hPictureWnd = NULL;\r\n\r\n   return ret;\r\n}\r\n<\/pre>\n<p>SetPicture is a key function that displays a bitmap in the layered window. It takes the bitmap that was loaded from an PNG with LoadImageFromResources and displays it in the layered window. As mentioned earlier it calls UpdateLayeredWindow to update the window.<\/p>\n<pre name=\"code\" class=\"cpp\">\r\nBOOL SetPicture(HBITMAP hbmp)\r\n{\r\n   if(g_hPictureWnd == NULL)\r\n      return FALSE;\r\n\r\n   BITMAP bm;\r\n   GetObject(hbmp, sizeof(bm), &bm);\r\n   SIZE sizebmp = {bm.bmWidth, bm.bmHeight};\r\n   \r\n   HDC hdcScreen = GetDC(g_hPictureWnd);\r\n   HDC hdcMem = CreateCompatibleDC(hdcScreen);\r\n   HBITMAP hbmpOld = (HBITMAP)SelectObject(hdcMem, hbmp);\r\n\r\n   BLENDFUNCTION blend = { 0 };\r\n   blend.BlendOp = AC_SRC_OVER;\r\n   blend.SourceConstantAlpha = 255;\r\n   blend.AlphaFormat = AC_SRC_ALPHA;\r\n\r\n   RECT rcwin;\r\n   GetWindowRect(g_hPictureWnd, &rcwin);\r\n\r\n   POINT ptSrc = {0};\r\n   POINT ptDest = {rcwin.left, rcwin.top};\r\n\r\n   UpdateLayeredWindow(\r\n      g_hPictureWnd, \r\n      hdcScreen, \r\n      &ptDest, \r\n      &sizebmp,\r\n      hdcMem, \r\n      &ptSrc, \r\n      RGB(0, 0, 0), \r\n      &blend, \r\n      ULW_ALPHA);\r\n\r\n   SelectObject(hdcMem, hbmpOld);\r\n   DeleteDC(hdcMem);\r\n   ReleaseDC(g_hPictureWnd, hdcScreen);\r\n\r\n   return TRUE;\r\n}\r\n<\/pre>\n<p>PictureTimerProc is the timer procedure we use to destroy the window after a specified interval since the last typed key elapsed.<\/p>\n<pre name=\"code\" class=\"cpp\">\r\nVOID CALLBACK PictureTimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)\r\n{\r\n   if(idEvent == g_timer)\r\n   {\r\n      ::KillTimer(hwnd, idEvent);\r\n      g_timer = 0;\r\n\r\n      DestroyPictureWindow();\r\n   }\r\n}\r\n<\/pre>\n<p>Make sure you call CoInitialize() to initialize the COM library for the main thread before the message loop begins in function main. Also make sure to call CoUninitialize() before the program ends.<\/p>\n<p>WndProc is the function where the messages sent to the main window are processed. We&#8217;ll handle WM_CHAR, and when E, M or S are pressed we load the appropriate image, create the layered window for the picture if not already created, and set the picture in the window. This is how the code looks:<\/p>\n<pre name=\"code\" class=\"cpp\">\r\n   case WM_CHAR:\r\n      {\r\n         HBITMAP hbmp = NULL;\r\n         switch((char)wParam)\r\n         {\r\n         case 'E': case 'e':\r\n            hbmp = LoadImageFromResources(MAKEINTRESOURCE(IDB_PNG1), _T(\"PNG\"));\r\n            break;\r\n         case 'M': case 'm':\r\n            hbmp = LoadImageFromResources(MAKEINTRESOURCE(IDB_PNG2), _T(\"PNG\"));\r\n            break;\r\n         case 'S': case 's':\r\n            hbmp = LoadImageFromResources(MAKEINTRESOURCE(IDB_PNG3), _T(\"PNG\"));\r\n            break;\r\n         default:\r\n            break;\r\n         }\r\n\r\n         if(hbmp != NULL)\r\n         {\r\n            if(g_hbmp != NULL)\r\n               DeleteObject(g_hbmp);\r\n            g_hbmp = hbmp;\r\n\r\n            if(g_hPictureWnd == NULL)\r\n            {\r\n               CreatePictureWindow(hInst, hWnd);\r\n            }\r\n\r\n            if(g_hPictureWnd != NULL)\r\n            {\r\n               if(SetPicture(hbmp))\r\n               {\r\n                  g_timer = SetTimer(hWnd, 1, 2000, PictureTimerProc);\r\n                  SetFocus(hWnd);\r\n               }\r\n            }\r\n         }\r\n      }\r\n      break;\r\n<\/pre>\n<p>And basically that is all. Just run the application and type E, M and S. You&#8217;ll see the images changing and 2 seconds after the last key is pressed the image is automatically hidden (as the layered window is destroyed).<\/p>\n<p>You can download the source code from here: <div class=\"wp-block-button\">\n<a  data-e-Disable-Page-Transition=\"true\" class=\"dlm-download-link dlm-download-default wp-block-button__link wp-element-button\" title=\"Version 1.0\" href=\"https:\/\/mariusbancila.ro\/blog\/download\/3493\/?tmstv=1791688324\" rel=\"nofollow\" id=\"download-link-3493\" data-redirect=\"false\" >\n\tTypePictures\t(<span class=\"dlm-download-count-value\">5734 downloads<\/span>\n\t)\n<\/a>\n<\/div>\n.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>There was a question on Stackoverflow about a C++ project displaying an image as you type. Here is the original question: I am writing a very simple program in C++ that listens to keyboard input, but what I want to output is much more difficult than I expected. For every key I press, I want &#8230; <a title=\"Display images as you type in C++\" class=\"read-more\" href=\"https:\/\/mariusbancila.ro\/blog\/2011\/08\/04\/display-images-as-you-type-in-cpp\/\" aria-label=\"Read more about Display images as you type in C++\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_uag_custom_page_level_css":"","advgb_blocks_editor_width":"","advgb_blocks_columns_visual_guide":"","_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false},"categories":[7],"tags":[451,173,285,284],"class_list":["post-1101","post","type-post","status-publish","format-standard","hentry","category-c","tag-c","tag-image","tag-wic","tag-winapi"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.1.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"A sample C++ project that displays images on screen as you type.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Marius Bancila\"\/>\n\t<meta name=\"keywords\" content=\"c++,winapi,image,wic\" \/>\n\t<link rel=\"canonical\" href=\"https:\/\/mariusbancila.ro\/blog\/2011\/08\/04\/display-images-as-you-type-in-cpp\/\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"en_US\" \/>\n\t\t<meta property=\"og:site_name\" content=\"Marius Bancila&#039;s Blog | About code. Mostly on C++\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"Display images as you type in C++\" \/>\n\t\t<meta property=\"og:description\" content=\"A sample C++ project that displays images on screen as you type.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/mariusbancila.ro\/blog\/2011\/08\/04\/display-images-as-you-type-in-cpp\/\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2011-08-04T16:28:18+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-07-02T14:32:18+00:00\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary\" \/>\n\t\t<meta name=\"twitter:title\" content=\"Display images as you type in C++\" \/>\n\t\t<meta name=\"twitter:description\" content=\"A sample C++ project that displays images on screen as you type.\" \/>\n\t\t<script type=\"application\/ld+json\" class=\"aioseo-schema\">\n\t\t\t{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2011\\\/08\\\/04\\\/display-images-as-you-type-in-cpp\\\/#article\",\"name\":\"Display images as you type in C++\",\"headline\":\"Display images as you type in C++\",\"author\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/#author\"},\"publisher\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#organization\"},\"image\":{\"@type\":\"ImageObject\",\"url\":\"\\\/blog\\\/wp-content\\\/uploads\\\/2011\\\/08\\\/earth.png\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2011\\\/08\\\/04\\\/display-images-as-you-type-in-cpp\\\/#articleImage\"},\"datePublished\":\"2011-08-04T18:28:18+02:00\",\"dateModified\":\"2019-07-02T16:32:18+02:00\",\"inLanguage\":\"en-US\",\"commentCount\":2,\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2011\\\/08\\\/04\\\/display-images-as-you-type-in-cpp\\\/#webpage\"},\"isPartOf\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2011\\\/08\\\/04\\\/display-images-as-you-type-in-cpp\\\/#webpage\"},\"articleSection\":\"C++, C++, image, WIC, winapi\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2011\\\/08\\\/04\\\/display-images-as-you-type-in-cpp\\\/#breadcrumblist\",\"itemListElement\":[{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog#listItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/#listItem\",\"name\":\"IT\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/#listItem\",\"position\":2,\"name\":\"IT\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/#listItem\",\"name\":\"Software\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog#listItem\",\"name\":\"Home\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/#listItem\",\"position\":3,\"name\":\"Software\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/c\\\/#listItem\",\"name\":\"C++\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/#listItem\",\"name\":\"IT\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/c\\\/#listItem\",\"position\":4,\"name\":\"C++\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/c\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2011\\\/08\\\/04\\\/display-images-as-you-type-in-cpp\\\/#listItem\",\"name\":\"Display images as you type in C++\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/#listItem\",\"name\":\"Software\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2011\\\/08\\\/04\\\/display-images-as-you-type-in-cpp\\\/#listItem\",\"position\":5,\"name\":\"Display images as you type in C++\",\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/c\\\/#listItem\",\"name\":\"C++\"}}]},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#organization\",\"name\":\"Marius Bancila's Blog\",\"description\":\"About code. Mostly on C++\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/#author\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/\",\"name\":\"Marius Bancila\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2011\\\/08\\\/04\\\/display-images-as-you-type-in-cpp\\\/#authorImage\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/a84dd2831d955c38355ddea55df4df260809b88f36408bc14fd4eab8f7f131c9?s=96&d=mm&r=g\",\"width\":96,\"height\":96,\"caption\":\"Marius Bancila\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2011\\\/08\\\/04\\\/display-images-as-you-type-in-cpp\\\/#webpage\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2011\\\/08\\\/04\\\/display-images-as-you-type-in-cpp\\\/\",\"name\":\"Display images as you type in C++\",\"description\":\"A sample C++ project that displays images on screen as you type.\",\"inLanguage\":\"en-US\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#website\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2011\\\/08\\\/04\\\/display-images-as-you-type-in-cpp\\\/#breadcrumblist\"},\"author\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/#author\"},\"creator\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/#author\"},\"datePublished\":\"2011-08-04T18:28:18+02:00\",\"dateModified\":\"2019-07-02T16:32:18+02:00\"},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/\",\"name\":\"Marius Bancila's Blog\",\"description\":\"About code. Mostly on C++\",\"inLanguage\":\"en-US\",\"publisher\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#organization\"}}]}\n\t\t<\/script>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"Display images as you type in C++","description":"A sample C++ project that displays images on screen as you type.","canonical_url":"https:\/\/mariusbancila.ro\/blog\/2011\/08\/04\/display-images-as-you-type-in-cpp\/","robots":"max-image-preview:large","keywords":"c++,winapi,image,wic","webmasterTools":{"miscellaneous":""},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/mariusbancila.ro\/blog\/2011\/08\/04\/display-images-as-you-type-in-cpp\/#article","name":"Display images as you type in C++","headline":"Display images as you type in C++","author":{"@id":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/#author"},"publisher":{"@id":"https:\/\/mariusbancila.ro\/blog\/#organization"},"image":{"@type":"ImageObject","url":"\/blog\/wp-content\/uploads\/2011\/08\/earth.png","@id":"https:\/\/mariusbancila.ro\/blog\/2011\/08\/04\/display-images-as-you-type-in-cpp\/#articleImage"},"datePublished":"2011-08-04T18:28:18+02:00","dateModified":"2019-07-02T16:32:18+02:00","inLanguage":"en-US","commentCount":2,"mainEntityOfPage":{"@id":"https:\/\/mariusbancila.ro\/blog\/2011\/08\/04\/display-images-as-you-type-in-cpp\/#webpage"},"isPartOf":{"@id":"https:\/\/mariusbancila.ro\/blog\/2011\/08\/04\/display-images-as-you-type-in-cpp\/#webpage"},"articleSection":"C++, C++, image, WIC, winapi"},{"@type":"BreadcrumbList","@id":"https:\/\/mariusbancila.ro\/blog\/2011\/08\/04\/display-images-as-you-type-in-cpp\/#breadcrumblist","itemListElement":[{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog#listItem","position":1,"name":"Home","item":"https:\/\/mariusbancila.ro\/blog","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/#listItem","name":"IT"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/#listItem","position":2,"name":"IT","item":"https:\/\/mariusbancila.ro\/blog\/category\/it\/","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/#listItem","name":"Software"},"previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog#listItem","name":"Home"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/#listItem","position":3,"name":"Software","item":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/#listItem","name":"C++"},"previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/#listItem","name":"IT"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/#listItem","position":4,"name":"C++","item":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/2011\/08\/04\/display-images-as-you-type-in-cpp\/#listItem","name":"Display images as you type in C++"},"previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/#listItem","name":"Software"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/2011\/08\/04\/display-images-as-you-type-in-cpp\/#listItem","position":5,"name":"Display images as you type in C++","previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/#listItem","name":"C++"}}]},{"@type":"Organization","@id":"https:\/\/mariusbancila.ro\/blog\/#organization","name":"Marius Bancila's Blog","description":"About code. Mostly on C++","url":"https:\/\/mariusbancila.ro\/blog\/"},{"@type":"Person","@id":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/#author","url":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/","name":"Marius Bancila","image":{"@type":"ImageObject","@id":"https:\/\/mariusbancila.ro\/blog\/2011\/08\/04\/display-images-as-you-type-in-cpp\/#authorImage","url":"https:\/\/secure.gravatar.com\/avatar\/a84dd2831d955c38355ddea55df4df260809b88f36408bc14fd4eab8f7f131c9?s=96&d=mm&r=g","width":96,"height":96,"caption":"Marius Bancila"}},{"@type":"WebPage","@id":"https:\/\/mariusbancila.ro\/blog\/2011\/08\/04\/display-images-as-you-type-in-cpp\/#webpage","url":"https:\/\/mariusbancila.ro\/blog\/2011\/08\/04\/display-images-as-you-type-in-cpp\/","name":"Display images as you type in C++","description":"A sample C++ project that displays images on screen as you type.","inLanguage":"en-US","isPartOf":{"@id":"https:\/\/mariusbancila.ro\/blog\/#website"},"breadcrumb":{"@id":"https:\/\/mariusbancila.ro\/blog\/2011\/08\/04\/display-images-as-you-type-in-cpp\/#breadcrumblist"},"author":{"@id":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/#author"},"creator":{"@id":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/#author"},"datePublished":"2011-08-04T18:28:18+02:00","dateModified":"2019-07-02T16:32:18+02:00"},{"@type":"WebSite","@id":"https:\/\/mariusbancila.ro\/blog\/#website","url":"https:\/\/mariusbancila.ro\/blog\/","name":"Marius Bancila's Blog","description":"About code. Mostly on C++","inLanguage":"en-US","publisher":{"@id":"https:\/\/mariusbancila.ro\/blog\/#organization"}}]},"og:locale":"en_US","og:site_name":"Marius Bancila's Blog | About code. Mostly on C++","og:type":"article","og:title":"Display images as you type in C++","og:description":"A sample C++ project that displays images on screen as you type.","og:url":"https:\/\/mariusbancila.ro\/blog\/2011\/08\/04\/display-images-as-you-type-in-cpp\/","article:published_time":"2011-08-04T16:28:18+00:00","article:modified_time":"2019-07-02T14:32:18+00:00","twitter:card":"summary","twitter:title":"Display images as you type in C++","twitter:description":"A sample C++ project that displays images on screen as you type."},"aioseo_meta_data":{"post_id":"1101","title":"Display images as you type in C++","description":"A sample C++ project that displays images on screen as you type.","keywords":[{"label":"C++","value":"C++"},{"label":"winapi","value":"winapi"},{"label":"image","value":"image"},{"label":"WIC","value":"WIC"}],"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"location":null,"local_seo":null,"breadcrumb_settings":null,"limit_modified_date":false,"ai":null,"created":"2021-03-18 21:13:02","updated":"2025-12-12 07:36:46","seo_analyzer_scan_date":null,"focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"author_meta":{"display_name":"Marius Bancila","author_link":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/"},"featured_img":null,"jetpack_publicize_connections":[],"uagb_featured_image_src":{"full":false,"thumbnail":false,"medium":false,"medium_large":false,"large":false,"1536x1536":false,"2048x2048":false},"uagb_author_info":{"display_name":"Marius Bancila","author_link":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/"},"uagb_comment_info":2,"uagb_excerpt":"There was a question on Stackoverflow about a C++ project displaying an image as you type. Here is the original question: I am writing a very simple program in C++ that listens to keyboard input, but what I want to output is much more difficult than I expected. For every key I press, I want&hellip;","coauthors":[],"tax_additional":{"categories":{"linked":["<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/\" class=\"advgb-post-tax-term\">C++<\/a>"],"unlinked":["<span class=\"advgb-post-tax-term\">C++<\/span>"]},"tags":{"linked":["<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/\" class=\"advgb-post-tax-term\">C++<\/a>","<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/\" class=\"advgb-post-tax-term\">image<\/a>","<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/\" class=\"advgb-post-tax-term\">WIC<\/a>","<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/\" class=\"advgb-post-tax-term\">winapi<\/a>"],"unlinked":["<span class=\"advgb-post-tax-term\">C++<\/span>","<span class=\"advgb-post-tax-term\">image<\/span>","<span class=\"advgb-post-tax-term\">WIC<\/span>","<span class=\"advgb-post-tax-term\">winapi<\/span>"]}},"comment_count":"2","relative_dates":{"created":"Posted 15 years ago","modified":"Updated 7 years ago"},"absolute_dates":{"created":"Posted on August 4, 2011","modified":"Updated on July 2, 2019"},"absolute_dates_time":{"created":"Posted on August 4, 2011 6:28 pm","modified":"Updated on July 2, 2019 4:32 pm"},"featured_img_caption":"","series_order":"","jetpack_shortlink":"https:\/\/wp.me\/pYNdv-hL","jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/posts\/1101","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/comments?post=1101"}],"version-history":[{"count":7,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/posts\/1101\/revisions"}],"predecessor-version":[{"id":3516,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/posts\/1101\/revisions\/3516"}],"wp:attachment":[{"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/media?parent=1101"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/categories?post=1101"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/tags?post=1101"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}