paintX is actually pretty easy to use. It can be used together with any activeX control which exposes a picture propertry (type: IPictureDisp). Basically, you need to call Set object.picture = PicDecoder.LoadPicture(FileName). The decoder does (almost) everything else, if it's installed.
Note that paintX is an image decoder, not an image displayer - that's why paintX isn't an activeX control, it's an activeX component (or automation server, or ole automation server - MS keeps changing the names), which means it does not have a user interface and cannot be simply dropped into a dialogbox.
The standard error handling methods work with paintX. This means that from Visual Basic, you can use On Error GoTo to specify a routine that will be called when something goes wrong while decoding.
To install paintX, you need to download paintX.zip and unpack it to the directory you'd like it to be in. WinZip is a good choice for a program to use to unpack it. After it's unpacked, paintX needs to be registered with windows. To do this, choose "Run..." from the start menu. Type 'c:\windows\system\regsvr32 c:\paintlib\paintX.dll', replacing the path names with the appropriate values for your system. To verify that it's installed, open paintX.xls with Excel97 and click on the bitmap. You should get a dialog asking for a directory. After you press 'go', all images in that directory should get displayed.
Visual Basic - LoadPicture
In this sample, MyImage is the image control that will display the picture. The pictures are always delivered in 256-color (8 bit) or true-color (32 bit) format. Pictures in other formats get promoted to the next higher format. For instance, 16-color pictures are delivered as 256-color pictures. As an exception, black-and-white tiff images are delivered as 2-color pictures. (This exception was coded because of the large number of fax viewers which need to display b/w tiffs.)
' This sub assumes an Image Control named MyImage is on the form Sub LoadPictureTest( Filename As String ) ' create the decoder Dim PicDecoder As New PaintX.PictureDecoder ' trap errors On Error Goto LoadError ' load the picture Set MyImage.Picture = PicDecoder.LoadPicture(Filename) ' redraw the form DoEvents Repaint ' done! Exit Sub ' Handle Errors LoadError: MsgBox Hex(Err.Number) & ":" & Err.Description End Sub
Visual Basic - LoadResPicture
You can also load a picture from a windows resource using LoadResPicture (ID).
' This sub assumes an Image Control named MyImage is on the form Sub LoadPictureResTest( ResID as Integer ) ' create the decoder Dim PicDecoder As New PaintX.PictureDecoder ' trap errors On Error Goto LoadError ' load the picture Set MyImage.Picture = PicDecoder.LoadResPicture(ResID) ' redraw the form DoEvents Repaint ' done! Exit Sub ' Handle Errors LoadError: MsgBox Hex(Err.Number) & ":" & Err.Description End Sub
LoadResPicture first looks for a resource of type RCDATA. Unfortunatly, the Visual Basic Resource Editor cannot insert RCDATA into a resource file. LoadResPicture will also look for a custom resource of type "PAINTX", if no resource of type RCDATA could be found.
One problem is that LoadResPicture always looks for the resource in the current *.exe. When you run from the IDE, you're not really running your program, you're running VB6.exe. If you call, say PictureDecoder.LoadResPicture(25), PaintX will get resource 25 from VB6.exe, or more likely nothing at all. The app will run correctly once compiled and run as a normal .exe.
Take a look at the VB example project VBPaintX. It demonstrates the following:
Using paintX from C++
In general, it's easier to just use paintlib directly from Visual C++. But if you're more comfortable using an ActiveX. component, this is how you do it: Create an image control on your form or dialogbox. (Insert activeX control "Microsoft Forms 2.0 Image"). Then add an #import "..\PaintX\paintx.dll" directive just after your #include directives. Now you can just use:
// Create the Decoder PAINTXLib::IPictureDecoderPtr pIPictureDecoder(__uuidof(PAINTXLib::PictureDecoder)); // decode the picture IPictureDispPtr MyPicture = (IPictureDispPtr)pIPictureDecoder->LoadPicture(_bstr_t("TEST.JPG")); // set the image m_Image.SetPicture(MyPicture);
See the Dr. Gui Article "Dr. GUI on Components, COM, and ATL", Part 8 in the MSDN library for more information about using ActiveX components in VC++ with "smart pointers".
COM error codes are a bit hard to use. Encoded in the HRESULT is the severity, the facility and the error code itself (SCODE).
If the facility is FACILITY_ITF (upper word 0x8004) then we have a third-party error code and we have to look at the error source ( VC++: _com_error::Source(), VB: Err.Source ) to determine which third-party caused the error condition. All PaintX errors have "PAINTX" as the error source. See except.h for a complete listing of the decoder errors.
HRESULT FACILITY SCODE Error 0x80040001 FACILITY_ITF 1 wrong signature 0x80040002 FACILITY_ITF 2 format unknown 0x80040006 FACILITY_ITF 6 format not supported 0x80040007 FACILITY_ITF 7 internal error of some sort 0x80040008 FACILITY_ITF 8 unknown file type 0x80040009 FACILITY_ITF 9 DIB too large 0x8004000B FACILITY_ITF 11 end of file
In case you're wondering where errors 3,4,5 and 10 are: these errors are mapped to the Win32 error codes:
If the upper word is SEVERITY_ERROR & FACILITY_WIN32 (0x8007), then we have an Win32-error.
HRESULT FACILITY SCODE Error 0x80070002 FACILITY_WIN32 2 file not found 0x80070003 FACILITY_WIN32 3 path not found 0x80070005 FACILITY_WIN32 5 access denied 0x8007000E FACILITY_WIN32 14 out of memory