How does one save bitmap image to a file in PNG format?

This is a closed topic which, IMO, was not addressed satisfactorily.

BACKGROUND

My O/S is 64-bit Win 7 Home Edition, and for about 3 years now, I have been successfully creating Win-32 apps using MS VS 2010 C++ Express. However, I have yet to decipher the mystery that is GDI and that which is WIC. NONE of the related code examples I've seen on this website or elsewhere work on my PC.

MY QUESTIONS

Here are my questions. Please, anyone, answer any of these as best you can.

(1) How does one save bitmap image to a file in PNG format?
The "answers" that I have seen to this question require GdiPlus.h and/or wincodec.h and/or a host of other include files that do not
compile on my PC under MS VS 2010 C++ Express or under MS VS 2013 C++ Express. My experience with these erstwhile solutions has been dismal.
For example, inclusion of the line
#include <Gdiplus.h>
in one of my source files generates over 100 errors during compilation.
ALL of the errors are syntax errors in SDK *.h files referenced by
Gdiplus.h. What gives?

(2) Do Express versions of Visual Studio not support GDI and WIC? If not, why don't MSDN and and other C++ website forums simply say so?

(2) VS 2010 and 2013 Express both support a LoadImage function that doesn't require inclusion of dozens of exotic *.h files. Why is there no corresponding SaveImage function?

(3) Alternatively, can anyone recommend a RELIABLE standalone console app that "converts" a graphics file from one format to another -- i.e., that reads a graphics file of one format and creates an equivalent file of another, user-specified graphics format? I am reluctant to throw money at some unknown vendor in exchange for virus-laden and/or misrepresented crap.

Thank you for attending to this. I would appreciate any and all replies rendered in grammatically decipherable standard English. Please proofread your replies before posting to ensure your usage of complete sentences devoid of omissions of verbs, conjunctions and prepositions.
Also, please define any technical terms you use whose definitions are not readily available somewhere on the internet.

For example, inclusion of the line
#include <Gdiplus.h>
in one of my source files generates over 100 errors during compilation.
What is the first few errors generated? Usually it happens bevause of either forgetting to include windows.h or because of improper content of stdafx.h.

LoadImage is created to load resources: icons, cursors, bmp images. It is not created to support more complex formats, nor to load images for modification. So there is no need for SaveImage.

Alternatively, can anyone recommend a RELIABLE standalone console app that "converts" a graphics file from one format to another
Imagemagic. Free, crossplatform, command line:
http://www.imagemagick.org/script/index.php
http://www.imagemagick.org/script/command-line-processing.php
Thank you for your prompt reply. I will check out ImageMagick as a stop gap measure but am still interested in learning how to accomplish the conversion/save internal to my app.

FYI: The first few lines of my stdafx.h file are:

#pragma once

#include "targetver.h"

#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
// Windows Header Files:
#include <windows.h>
#include <gdiplus.h>
#include <stdio.h>
using namespace Gdiplus;

// C RunTime Header Files
#include <stdint.h>
#include <WinUser.h>
#include <WinBase.h>
#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <wingdi.h>
#include <commctrl.h>
#include <winuser.h>
#include <cstdlib>
#include <ctime>
#include <stdlib.h>
#include <d2d1.h>
#include <wincodec.h>

// TODO: reference additional headers your program requires here
#include "Resource.h"

The first few lines of the output produced by Build follow. Most (not all) are syntax errors. All are generated in gdiplus.h or in the header files it references.

1>------ Build started: Project: BitmapLab, Configuration: Debug Win32 ------
1> stdafx.cpp
1>------ Rebuild All started: Project: BitmapLab, Configuration: Debug Win32 ------
1> stdafx.cpp
1>c:\program files (x86)\microsoft sdks\windows\v7.0a\include\gdiplusimaging.h(74): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\program files (x86)\microsoft sdks\windows\v7.0a\include\gdiplusimaging.h(74): error C2440: 'initializing' : cannot convert from 'const char [37]' to 'int'
1> There is no context in which this conversion is possible
1>c:\program files (x86)\microsoft sdks\windows\v7.0a\include\gdiplusimaging.h(74): error C2146: syntax error : missing ';' before identifier 'IImageBytes'
1>c:\program files (x86)\microsoft sdks\windows\v7.0a\include\gdiplusimaging.h(74): error C2470: 'IImageBytes' : looks like a function definition, but there is no parameter list; skipping apparent body
1>c:\program files (x86)\microsoft sdks\windows\v7.0a\include\gdiplusimaging.h(74): error C2059: syntax error : 'public'
1>c:\program files (x86)\microsoft sdks\windows\v7.0a\include\gdiplusimaging.h(280): error C2146: syntax error : missing ';' before identifier 'id'
1>c:\program files (x86)\microsoft sdks\windows\v7.0a\include\gdiplusimaging.h(280): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\program files (x86)\microsoft sdks\windows\v7.0a\include\gdiplusimaging.h(280): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\program files (x86)\microsoft sdks\windows\v7.0a\include\gdiplusheaders.h(384): error C2061: syntax error : identifier 'IStream'
1>c:\program files (x86)\microsoft sdks\windows\v7.0a\include\gdiplusheaders.h(395): error C2061: syntax error : identifier 'IStream'
1>c:\program files (x86)\microsoft sdks\windows\v7.0a\include\gdiplusheaders.h(405): error C2061: syntax error : identifier 'IStream'
1>c:\program files (x86)\microsoft sdks\windows\v7.0a\include\gdiplusheaders.h(443): error C2061: syntax error : identifier 'PROPID'
1>c:\program files (x86)\microsoft sdks\windows\v7.0a\include\gdiplusheaders.h(444): error C2061: syntax error : identifier 'PROPID'
1>c:\program files (x86)\microsoft sdks\windows\v7.0a\include\gdiplusheaders.h(445): error C2061: syntax error : identifier 'PROPID'
1>c:\program files (x86)\microsoft sdks\windows\v7.0a\include\gdiplusheaders.h(453): error C2061: syntax error : identifier 'PROPID'
1>c:\program files (x86)\microsoft sdks\windows\v7.0a\include\gdiplusheaders.h(471): error C2535: 'Gdiplus::Image::Image(void)' : member function already defined or declared
1> c:\program files (x86)\microsoft sdks\windows\v7.0a\include\gdiplusheaders.h(384) : see declaration of 'Gdiplus::Image::Image'
1>c:\program files (x86)\microsoft sdks\windows\v7.0a\include\gdiplusheaders.h(505): error C2061: syntax error : identifier 'IStream'
1>c:\program files (x86)\microsoft sdks\windows\v7.0a\include\gdiplusheaders.h(516): error C2061: syntax error : identifier 'IStream'
1>c:\program files (x86)\microsoft sdks\windows\v7.0a\include\gdiplusheaders.h(758): error C2061: syntax error : identifier 'IStream'
1>c:\program files (x86)\microsoft sdks\windows\v7.0a\include\gdiplusheaders.h(813): error C2061: syntax error : identifier 'IStream'
1>c:\program files (x86)\microsoft sdks\windows\v7.0a\include\gdiplusheaders.h(813): error C2535: 'Gdiplus::Metafile::Metafile(void)' : member function already defined or declared
1> c:\program files (x86)\microsoft sdks\windows\v7.0a\include\gdiplusheaders.h(758) : see declaration of 'Gdiplus::Metafile::Metafile'
1>c:\program files (x86)\microsoft sdks\windows\v7.0a\include\gdiplusheaders.h(820): error C2061: syntax error : identifier 'IStream'
1>c:\program files (x86)\microsoft sdks\windows\v7.0a\include\gdiplusheaders.h(820): error C2535: 'Gdiplus::Metafile::Metafile(void)' : member function already defined or declared
1> c:\program files (x86)\microsoft sdks\windows\v7.0a\include\gdiplusheaders.h(758) : see declaration of 'Gdiplus::Metafile::Metafile'
1>c:\program files (x86)\microsoft sdks\windows\v7.0a\include\gdiplusheaders.h(829): error C2061: syntax error : identifier 'IStream'
1>c:\program files (x86)\microsoft sdks\windows\v7.0a\include\gdiplusheaders.h(829): error C2535: 'Gdiplus::Metafile::Metafile(void)' : member function already defined or declared
1> c:\program files (x86)\microsoft sdks\windows\v7.0a\include\gdiplusheaders.h(758) : see declaration of 'Gdiplus::Metafile::Metafile'
1>c:\program files (x86)\microsoft sdks\windows\v7.0a\include\gdiplusheaders.h(855): error C2061: syntax error : identifier 'IStream'
1>c:\program files (x86)\microsoft sdks\windows\v7.0a\include\gdiplusheaders.h(923): error C2535: 'Gdiplus::Metafile::Metafile(void)' : member function already defined or declared
1> c:\program files (x86)\microsoft sdks\windows\v7.0a\include\gdiplusheaders.h(758) : see declaration of 'Gdiplus::Metafile::Metafile'
1>c:\program files (x86)\microsoft sdks\windows\v7.0a\include\gdiplusflat.h(1133): error C2065: 'IStream' : undeclared identifier
1>c:\program files (x86)\microsoft sdks\windows\v7.0a\include\gdiplusflat.h(1133): error C2065: 'stream' : undeclared identifier
1>c:\program files (x86)\microsoft sdks\windows\v7.0a\include\gdiplusflat.h(1133): error C2065: 'image' : undeclared identifier
1>c:\program files (x86)\microsoft sdks\windows\v7.0a\include\gdiplusflat.h(1133): error C2275: 'Gdiplus::GpImage' : illegal use of this type as an expression
1> c:\program files (x86)\microsoft sdks\windows\v7.0a\include\gdiplusgpstubs.h(61) : see declaration of 'Gdiplus::GpImage'
1>c:\program files (x86)\microsoft sdks\windows\v7.0a\include\gdiplusflat.h(1133): warning C4229: anachronism used : modifiers on data are ignored
1>c:\program files (x86)\microsoft sdks\windows\v7.0a\include\gdiplusflat.h(1133): error C2078: too many initializers
1>c:\program files (x86)\microsoft sdks\windows\v7.0a\include\gdiplusflat.h(1139): error C2065: 'IStream' : undeclared identifier
1>c:\program files (x86)\microsoft sdks\windows\v7.0a\include\gdiplusflat.h(1139): error C2065: 'stream' : undeclared identifier
1>c:\program files (x86)\microsoft sdks\windows\v7.0a\include\gdiplusflat.h(1139): error C2065: 'image' : undeclared identifier


#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
This is the culpit IIRC. That "rarely-used stuff" is essential for GDI. Remove this line
Last edited on
You're just missing objbase.h (the header which defines stuff for COM), which is what the compiler is whinging about -- it doesn't know what the MIDL_INTERFACE() macro, etc are.

But removing WIN32_LEAN_AND_MEAN, as MiiNiPaa isn't a bad idea if you don't know your way round the Windows headers. Esp. as you're using a precompiled header.

What WIN32_LEAN_AND_MEAN means is that you just want the core of the WinAPI, which includes GDI and USER.

When you are going to include loads of headers it pays to be disciplined. Grouping is a good idea, if done right. And ordering header (alphabetically or whatever) can help. Headers should ideally not assume other headers have been included, which means gdiplusimaging.h deserves a black mark! This might have helped you spot the fact that you'd #included some headers two or more times.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#pragma once

#include "targetver.h"

#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
// Windows Header Files:
#include <windows.h>
#include <objbase.h>
#include <gdiplus.h>
#include <stdio.h>     // NOT A WINDOWS HEADER
using namespace Gdiplus;

// C RunTime Header Files
#include <stdint.h>
#include <WinUser.h>   // A WINDOWS HEADER (NOT NEEDED AS PART OF CORE)
#include <WinBase.h>  // A WINDOWS HEADER (NOT NEEDED AS PART OF CORE)
#include <stdlib.h> // DUPLICATE
#include <stdio.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <wingdi.h>  // A WINDOWS HEADER (NOT NEEDED AS PART OF CORE)
#include <commctrl.h>  // A WINDOWS HEADER
#include <winuser.h>  // A WINDOWS HEADER  (NOT NEEDED AS PART OF CORE)
#include <cstdlib> // C++ EQUIV OF stdlib.h
#include <ctime> // C++ EQUIV OF time.h
#include <stdlib.h> // DUPLICATE
#include <d2d1.h>  // A WINDOWS HEADER
#include <wincodec.h>  // A WINDOWS HEADER

// TODO: reference additional headers your program requires here
#include "Resource.h" 


is better as, where I've:
1. fixed the grouping
2. removed the unnecessary core WinAPI headers
3. used the C++ header rather than C header when available

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#pragma once

#include "targetver.h"

#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers

// Windows Header Files:
#include <windows.h>
#include <wincodec.h>  // WIC API
#include <commctrl.h>  // common controls
#include <d2d1.h>      // Direct2D API
#include <objbase.h>   // COM

#include <gdiplus.h>
using namespace Gdiplus;

// Standard C++ Header Files
#include <cstdlib>
#include <cstdio>
#include <cstdint>
#include <cmath>
#include <cstring>
#include <ctime>

// malloc, free, ... are available when you #include <cstdlib> and
// memcmp, ... when you include <cstring> so I think these are pointless
// (but not 100% sure...)
#include <malloc.h>
#include <memory.h>

// Microsoft CRT specific headers
#include <tchar.h>

// TODO: reference additional headers your program requires here
#include "Resource.h" 


I prefer not to #include resource.h in stdafx.h as it's only required by the GUI classes.

Andy

PS Also see...

"How to use code tags"
http://www.cplusplus.com/articles/jEywvCM9/

1
2
3
4
5
6
7
8
9
10
// little C++ Shell cog wheel button ---->
// (if missing try refreshing your browser)
#include <iostream>
using namespace std;

int main() {
    cout << "Hello code tags!\n";

    return 0;
}

Last edited on
SUCCESS! My thanks to all of you who helped me arrive at a solution. For what it's worth, here is the function I came up with, derived from sample code presented in
https://msdn.microsoft.com/en-us/library/windows/desktop/ee719871(v=vs.85).aspx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
//==============================================================================
// MODULE NAME:  SaveBitmapAsPNG.cpp 
//
// REVISION HISTORY:
// 
//   28 June 2015   Rob Hoech
//     Original Release 
//
// DESCRIPTION: 
// 
//   This module contains the source code for generic support function 
//     HRESULT SaveBitmapAsPNG(
//         char *FileSpec
//       , HBITMAP hBitmap
//       ); 
//   Function SaveBitmapAsPNG() saves the bitmap variable specified by operand 
//   hBitmap to PNG file identified by character array szFileSpecPNG, where 
//   szFileSpecPNG is the concatenation of the directory path and filename 
//   components of operand szFileSpec and the extension ".png".  
//
// USAGE:  
//
//   hr = SaveBitmapAsPNG(
//       char *FileSpec
//     , HBITMAP hBitmap
//     ); 
//
//==============================================================================
#include "stdafx.h"

//--------------------------------------------------------------------------------
// Global Variables:
//--------------------------------------------------------------------------------
extern clasAppInfo  *AppInfo;

//--------------------------------------------------------------------------------
// Function Declarations:
//--------------------------------------------------------------------------------
HRESULT SaveBitmapAsPNG(
    char *szFileSpec
  , HBITMAP hBitmap
  )  
{
  char FileSpecPNG[LenFilespecMAX+1];
  char tstr[2000];

  //--------------------------------------------------------------------------------
  // Support for save to PNG and ICON.  
  //--------------------------------------------------------------------------------
  wchar_t wcstring[LenFilespecMAX+1];
  size_t NumCharsConverted;
  
  IWICImagingFactory *piFactory = NULL;
  IWICBitmapEncoder *piEncoder = NULL;
  IWICBitmapFrameEncode *piBitmapFrame = NULL;
  IPropertyBag2 *piPropertybag = NULL;
  
  IWICStream *piStream = NULL;
  UINT uiWidth = 640;
  UINT uiHeight = 480;
  HRESULT hr;

  
  //========================================================================
  // Processing.  
  //========================================================================
  //--------------------------------------------------------------------------------
  // Create BITMP object.
  //--------------------------------------------------------------------------------
  BITMAP *pBitmap = new BITMAP; 
  GetObject(hBitmap,sizeof(BITMAP),pBitmap);
  //--------------------------------------------------------------------------------
  // Create Output Filename.
  //--------------------------------------------------------------------------------
  clasFilespecInfo *FileSpecInfo = NULL;
  FileSpecInfo = new clasFilespecInfo(szFileSpec);
  if (   FileSpecInfo->DirIsValid()
      && FileSpecInfo->FnameIsValid()
      && FileSpecInfo->DirExists()
      && !FileSpecInfo->FnameIsWild()
      )
  {
    strcpy(FileSpecPNG,FileSpecInfo->szDir());
    strcat(FileSpecPNG,FileSpecInfo->szNameLessExt());
    strcat(FileSpecPNG,".png");
    delete FileSpecInfo;
  }
  else
  {
    delete FileSpecInfo;
    return 0;
  }
      
  if (0)
  {
    //X BITMAP *pBitmap = new BITMAP; 
    //X GetObject(hBitmap,sizeof(BITMAP),pBitmap);
    //X hBitmap->Save(szFspecBitmapSAVE, System::Drawing::Imaging::ImageFormat::Png);
    //X delete pBitmap;
  }
  else
  {
    //--------------------------------------------------------------------------------
    // Processing.  
    //--------------------------------------------------------------------------------
    // Initialize COM
    CoInitialize(NULL);
    // The factory pointer
    piFactory = NULL;
    hr = CoCreateInstance(
        CLSID_WICImagingFactory
      , NULL
      , CLSCTX_INPROC_SERVER
      , IID_IWICImagingFactory
      , (LPVOID*) &piFactory
      );
    
    if (SUCCEEDED(hr))
    {
      hr = piFactory->CreateStream(&piStream);
    }
    
    if (SUCCEEDED(hr))
    {
      mbstowcs_s(&NumCharsConverted, wcstring, (sizeof FileSpecPNG), FileSpecPNG, strlen(FileSpecPNG)+1);
      hr = piStream->InitializeFromFilename(wcstring, GENERIC_WRITE);
    }
    
    if (SUCCEEDED(hr))
    {
      hr = piFactory->CreateEncoder(GUID_ContainerFormatPng, NULL, &piEncoder);
    }
  
    if (SUCCEEDED(hr))
    {
      hr = piEncoder->Initialize(piStream, WICBitmapEncoderNoCache);
    }
    
    if (SUCCEEDED(hr))
    {
      hr = piEncoder->CreateNewFrame(&piBitmapFrame, &piPropertybag);
    }
    
    if (SUCCEEDED(hr))
    {        
      //X   // This is how you customize the TIFF output.
      //X   PROPBAG2 option = { 0 };
      //X   option.pstrName = L"PngCompressionMethod";
      //X   VARIANT varValue;    
      //X   VariantInit(&varValue);
      //X   varValue.vt = VT_UI1;
      //X   varValue.bVal = WICPngCompressionZIP;      
      //X   hr = piPropertybag->Write(1, &option, &varValue);        
      if (SUCCEEDED(hr))
      {
        hr = piBitmapFrame->Initialize(piPropertybag);
      }
    }
    
    if (SUCCEEDED(hr))
    {
      hr = piBitmapFrame->SetSize(UINT(pBitmap->bmWidth), UINT(pBitmap->bmHeight));
      if (!SUCCEEDED(hr))
        sprintf(tstr,"SetSize() returned HRESULT = %08x.\n", long(hr));
    }
    
    WICPixelFormatGUID formatGUID = GUID_WICPixelFormat24bppBGR;
    if (SUCCEEDED(hr))
    {
      hr = piBitmapFrame->SetPixelFormat(&formatGUID);
    }
    
    if (SUCCEEDED(hr))
    {
      // We're expecting to write out 24bppRGB. Fail if the encoder cannot do it.
      hr = IsEqualGUID(formatGUID, GUID_WICPixelFormat24bppBGR) ? S_OK : E_FAIL;
    }
    
    //X if (SUCCEEDED(hr))
    //X {
    //X   //X UINT cbStride = (pBitmap->bmWidth * pBitmap->bmBitsPixel + 7)/8;   /*  **WICGetStride** */
    //X   //X UINT cbBufferSize = pBitmap->bmHeight * cbStride;
    //X   UINT cbStride = pBitmap->bmWidthBytes;
    //X   UINT cbBufferSize = pBitmap->bmHeight * cbStride;
    //X   BYTE *pbBuffer = new BYTE[cbBufferSize];
    //X   if (pbBuffer != NULL)
    //X   {
    //X     //X for (UINT i = 0; i < cbBufferSize; i++)
    //X     //X   pbBuffer[i] = static_cast<BYTE>(rand());
    //X     //X hr = piBitmapFrame->WritePixels(uiHeight, cbStride, cbBufferSize, pbBuffer);
    //X     hr = piBitmapFrame->WritePixels(pBitmap->bmHeight, pBitmap->bmWidthBytes, cbBufferSize, pBitmap->bmBits);
    //X     delete[] pbBuffer;
    //X   }
    //X   else
    //X   {
    //X     hr = E_OUTOFMEMORY;
    //X   }
    //X }
    
    if (SUCCEEDED(hr))
    {
      UINT i,j,k;
      UINT cbBufferSize = pBitmap->bmHeight*pBitmap->bmWidthBytes;
      BYTE *pbBuffer = new BYTE[cbBufferSize];
      if (pbBuffer != NULL)
      {
        BYTE *pByteDST, *pByteSRC, *pB;
        pB = (BYTE*)pBitmap->bmBits;
        k = 0;
        pByteSRC = pB + cbBufferSize - pBitmap->bmWidthBytes;
        for (i=0; i<pBitmap->bmHeight; i++)
        {
          for (j=0; j<pBitmap->bmWidthBytes; j++)
            pbBuffer[k++] = *(pByteSRC++);
          pByteSRC -= 2*pBitmap->bmWidthBytes;
        }
        //X for (k=0; k<cbbuffersize; k++)
        //x   pbBuffer[k] = *(pB++);
        hr = piBitmapFrame->WritePixels(pBitmap->bmHeight, pBitmap->bmWidthBytes
          , cbBufferSize, pbBuffer);
        delete pbBuffer;
      }
    }
    
    if (SUCCEEDED(hr))
      hr = piBitmapFrame->Commit();
    
    if (SUCCEEDED(hr))
      hr = piEncoder->Commit();
    
    if (piFactory)
      piFactory->Release();
    if (piBitmapFrame)
      piBitmapFrame->Release();
    if (piEncoder)
      piEncoder->Release();
    if (piStream)
      piStream->Release();
    delete pBitmap;
    return hr;
  }
};

Last edited on
If you want your function to be preserved for posterity, please 'tag' it (inc. fixing the formatting -- esp indenting -- if it has gone messed up!)

"How to use code tags"
http://www.cplusplus.com/articles/jEywvCM9/

Andy

PS And I mean go back an edit your post, rather the repost.
Last edited on
done
Topic archived. No new replies allowed.