|
I don't understand the critics. The present version worked immediately, fast, clean and simple ! The resulting exe is just 28 KB in size and displays the image correctly.
Copied the code from the HTML page directly into a .C-file in MS Visual Studio, created a simple SDI main program, moved the function calls and typedef into a header file and i was ready to show the images....
Good job, Jacob
Rob
|
|
|
|
|
Please post a complete workable project, not just the functions.
|
|
|
|
|
I tried in MFC Project in the following code : But, i did not get proper solution.I have no error & warning .
void CImageDlg::OpenGraphicA(char *name1)
{
IPicture *Ipic = NULL;
SIZE sizeInHiMetric,sizeInPix;
const int HIMETRIC_PER_INCH = 2540;
HDC hDCScreen = ::GetDC(m_hWnd);
HRESULT hr;
int nPixelsPerInchX = ::GetDeviceCaps(hDCScreen, LOGPIXELSX);
int nPixelsPerInchY = ::GetDeviceCaps(hDCScreen, LOGPIXELSY);
unsigned short OlePathName[512];
::ReleaseDC(NULL,hDCScreen);
mbstowcs(OlePathName,name1,strlen(name1)+1);
hr = ::OleLoadPicturePath(OlePathName,
NULL,
0,
0,
IID_IPicture,
(void **)(&Ipic));
if (hr)
MessageBox("Error");
if (Ipic) {
// get width and height of picture
hr = Ipic->get_Width(&sizeInHiMetric.cx);
if (!SUCCEEDED(hr))
goto err;
Ipic->get_Height(&sizeInHiMetric.cy);
if (!SUCCEEDED(hr))
goto err;
// convert himetric to pixels
sizeInPix.cx = (nPixelsPerInchX * sizeInHiMetric.cx +
HIMETRIC_PER_INCH / 2) / HIMETRIC_PER_INCH;
sizeInPix.cy = (nPixelsPerInchY * sizeInHiMetric.cy +
HIMETRIC_PER_INCH / 2) / HIMETRIC_PER_INCH;
ImageInfo.sizeInPix = sizeInPix;
ImageInfo.sizeInHiMetric = sizeInHiMetric;
ImageInfo.Ipic = Ipic;
ImageInfo.Path = name1;
// return Ipic;
}
err:
MessageBox("Error");
// return 0;
}
void CImageDlg::DisplayGraphicA(HWND hwnd,HDC pDC)
{
IPicture *Ipic = ImageInfo.Ipic;
DWORD dwAttr = 0;
HBITMAP Bmp,BmpOld;
RECT rc;
HRESULT hr;
HPALETTE pPalMemOld;
if (Ipic != NULL)
{
// get palette
OLE_HANDLE hPal = 0;
HPALETTE hPalOld=NULL,hPalMemOld=NULL;
hr = Ipic->get_hPal(&hPal);
if (!SUCCEEDED(hr))
return;
if (hPal != 0)
{
hPalOld = ::SelectPalette(pDC,(HPALETTE)hPal,FALSE);
::RealizePalette(pDC);
}
// Fit the image to the size of the client area. Change this
// For more sophisticated scaling
::GetClientRect(hwnd,&rc);
// transparent?
if (SUCCEEDED(Ipic->get_Attributes(&dwAttr)) ||
(dwAttr & PICTURE_TRANSPARENT))
{
// use an off-screen DC to prevent flickering
HDC MemDC = CreateCompatibleDC(pDC);
Bmp = CreateCompatibleBitmap(pDC,ImageInfo.sizeInPix.cx,ImageInfo.sizeInPix.cy);
BmpOld = (HBITMAP)SelectObject(MemDC,Bmp);
pPalMemOld = NULL;
if (hPal != 0)
{
hPalMemOld = SelectPalette(MemDC,(HPALETTE)hPal, FALSE);
RealizePalette(MemDC);
}
/* Use this to show the left corner
rc.left = rc.top = 0;
rc.right = ImageInfo.sizeInPix.cx;
rc.bottom = ImageInfo.sizeInPix.cy;
*/
// display picture using IPicture::Render
hr = Ipic->Render(MemDC,
0,
0,
rc.right,
rc.bottom,
0,
ImageInfo.sizeInHiMetric.cy,
ImageInfo.sizeInHiMetric.cx,
-ImageInfo.sizeInHiMetric.cy,
&rc);
BitBlt(pDC,0, 0, ImageInfo.sizeInPix.cx,
ImageInfo.sizeInPix.cy,
MemDC, 0, 0, SRCCOPY);
SelectObject(MemDC,BmpOld);
if (pPalMemOld) SelectPalette(MemDC,pPalMemOld, FALSE);
DeleteObject(Bmp);
DeleteDC(MemDC);
}
else
{
// display picture using IPicture::Render
Ipic->Render(pDC,
0,
0,
rc.right,
rc.bottom,
0,
ImageInfo.sizeInHiMetric.cy,
ImageInfo.sizeInHiMetric.cx,
-ImageInfo.sizeInHiMetric.cy,
&rc);
}
if (hPalOld != NULL) SelectPalette(pDC,hPalOld, FALSE);
if (hPal) DeleteObject((HPALETTE)hPal);
}
}
|
|
|
|
|
What causes this error?
'Render' : is not a member of 'IPicture'
My includes are olectl.h,oleaut.h,ocidl.h and ole32.lib, olepro32.lib
|
|
|
|
|
Well I linked with
ole32.lib oleaut32.lib uuid.lib
and worked fine when in 16 bit color mode, but with 256 color after twice openfiles the system hang-up...
But if I comment the line:
if (hPal) DeleteObject(hPal);
the thing work fine, but this is wrong. It's not?
Someone can help?
|
|
|
|
|
Seen on MS doc: "A picture object created using OleLoadPicture always has ownership of its internal resources (fOwn==TRUE is implied)."
OleLoadPicturePath (used by this code) works the same way.
Then, if you read the doc of IPicture::get_hPal you find:
"Notes to Callers
If the picture object has ownership of the picture, it also has ownership of the palette and will destroy it when the object is itself destroyed. Otherwise the caller owns the palette. The fOwn parameter to OleCreatePictureIndirect determines ownership. OleLoadPicture sets fOwn to TRUE to indicate that the picture object owns the palette."
The result is that there should be no call to DeleteObject(hPal) (so you were right to remove this call).
Otherwise, even with bugs, I find this code useful as an example to use IPalette. I thank the author for that.
|
|
|
|
|
Your statement about LCC being a better compiler are false. VC++ is by FAR a better compiler with a lot of optimizations that LCC does not have. I'm not saying VC++ is perfect because it isn't, but it's the best we have for windows at the moment.
Your comments about the size of the executable are ignorant. Maybe if you knew how to use both LCC and VC++ you would understand why the default LCC executable is smaller then the default VC++ executable.
Thirdly, this will not load JPEG images on windows 95/98/NT since this wasn't added until ME/2K to Windows. When designing source code for people to use it would be best if you stated the limitations, which could be found by reading MSDN. If you look at the good projects on this site they nearly always work across all the Windows Systems.
I hope you will use this message constructively to improve your programming skills.
|
|
|
|
|
"I'm not saying VC++ is perfect because it isn't, but it's the best we have for windows at the moment."
Haha, funny. I hope you're not seriuos.
Every test shows that Intel's C compiler is by far the best C and C++ compiler for Windows.
And I know a couple of compilers that produce smaller executables than VC++, and even if I haven't tried LCC I wouldn't be supprise if it produces smaller files than VC++.
But the real issue here isn't if one compiler produces smaller files, the important thing is that C is smaller and faster than C++, and that's why this is a great article.
|
|
|
|
|
Bullshit!
lcc-win32 is great!
and the code run fine in my Win95...
|
|
|
|
|
really to hell with VC and .NET architecture,
LCC, and GCC rock, who the hell needs the stupid additional dozzens of code generated by dumb head VC. Every developer tries to have minimal binaries so that they are easily distributable.
You write what you think, but do not care about the effort of the person who is giving you a free source, if it is not useful to you and you cant write two words of appreciation, then goto hell and dont join the discussion thread.
Author has done a great job, and was tryign to differentiate between the minimum possible output of the final executable. Did he force you to download and/or discuss his resources ?
Quoting everything comes to your stupid brain, and then saying "I hope you will use this message constructively to improve your programming skills." does not heal up the wounds . What do yo uknow abotu the strfucture of VC compiler, tell me streight, I would like to have debate on it 'WITH YOU'.
Now, when directX has also been made embedable with c++ applciations and made available opensource in the form of libraries and headers [so that developers dont have to ship the shared DLLs], you will come to say, this is not workign properly as Microsoft directX Dynamic Linked Libraries.
Few questions for you,
1.how many technologies you know, especially compilers ?
2.can you compile pure windows API source on Linux ??????I CAN.
3.Did you ever create a compiler or even an interpreter or IDE ?
I am sure all will be
1. No
2. No
3. No
Then why the heck you are criticizing a person who comes with a very good source? although he forgot to mention the platform compatibility.
btw nice job Mr.Author.
|
|
|
|
|
Apart from the other valid complaints about your source code, I find it an absolute waste to tell you the truth. It's neither simple nor is it powerful by all means nor is it beautiful -- yet you stated that it would be all of the above. Let me propose an alternative approach: if I ever needed a jpg/gif/bmp/png/... displayed I'd merely misuse a listview control. Without headers, possibly even without a frame and without any items in it. To display the image, you only need to load it as a background image and resize the control accordingly. Probably no more than 5 lines of code....
Other than that: Thanks for acting as a living example for the inferiority of open source software.
|
|
|
|
|
Dear Anonymous:
Thanks for your contribution.
It is really a good idea.
I tried it, and it works without problems.
I have to confess that I did not learnt all the windows API by heart and that I did not knew that a listview control will display an image, incorporating the code I presented in the example of course. If you do not do a CoInitialize() before, the listview will not display anything, so I deduce that it is using the same IPicture interface.
As to your "Thanks for acting as a living example of the inferiority of open source software" just this: I try to share my code with others. I dare even to publish it and to ask my fellow programmers for his/her opinions, risking meeting people like you.
Sincerely
Jacob Navia
|
|
|
|
|
Jacob Navia wrote:
As to your "Thanks for acting as a living example of the inferiority of open source software" just this: I try to share my code with others. I dare even to publish it and to ask my fellow programmers for his/her opinions, risking meeting people like you.
Good Response, Jacob!
Notice, there is not even a name attached to the dissing message either.
Certainly Open Source can provide some less-than-optimum code, but the beauty of it is IT CAN BE FIXED. And IT IS REVIEWED. Even by persons as ill-mannered as the original poster. And you don't need to buy the next version to get the bug fixes.
Rufus
|
|
|
|
|
I have written a 4k intro in Visual C++ which did a whole lot more than this. It's got a softsynth, and uses OpenGL for graphics.
http://www.pouet.net/prod.php?which=5199
|
|
|
|
|
I applaud your decision to contribute your first article to CodeProject. However, the code you submitted does not work, and shows that you could not have possibly tested the code before you submitted it. Moreover, some of your coding practices would be totally unacceptable in any production environment.
For starters, the function ::OleLoadPicturePath() returns a pointer to the IPicture interface. This object is initialized by ::OleLoadPicturePath() , complete with the handle of the bitmap. However, in your code, you never reference the get_Handle method, so the bitmap never gets displayed.
The code itself contains several questionable items. First, the ImageInfo variable is a global, so use of the code for multiple images is out of the question.
Second, the call to ::OleLoadPicturePath() is incorrect. Instead of
HRESULT hr = OleLoadPicturePath(OlePathName,
NULL,
0,
0,
&IID_IPicture,
(void *)(&Ipic));
the correct parameters are:
HRESULT hr = OleLoadPicturePath(OlePathName,
NULL,
0,
0,
IID_IPicture,
(void **) (&Ipic));
Third, the function
void DisplayGraphic(HWND hwnd,HDC *pDC)
requires passing a pointer to a HDC. This is not only inconsistent with general Windows API usage, it is inconsistent within the code presented in the article. There are many places in the code which use this pointer, for example:
hPalOld = SelectPalette(pDC,hPal,FALSE);
Note that the function SelectPalette requires a HDC, not a pointer to a HDC.
Fourth, when the methods of the IPicture (Ipic) object are invoked, they are called via reference to "lpVtbl". For example, the Render method is called like this:
hr = Ipic->lpVtbl->Render(Ipic,MemDC,...
This syntax is incorrect in Microsoft VC++. In order to compile correctly, the code must be written as:
hr = Ipic->Render(MemDC,...
To summarize, you make claims about how small this code is when compiled, but it is hard to see how it could ever work correctly. I know nothing about the lcc-win32 compiler, but for most of the people on CodeProject, it is irrelevant, no matter how good it is. If you want to post more articles on CodeProject, my suggestion would be to test your code with MS VC++.
|
|
|
|
|
"Fourth, when the methods of the IPicture (Ipic) object are invoked, they are called via reference to "lpVtbl". For example, the Render method is called like this:
hr = Ipic->lpVtbl->Render(Ipic,MemDC,...
This syntax is incorrect in Microsoft VC++. In order to compile correctly, the code must be written as:
hr = Ipic->Render(MemDC,..."
What is the difference of C and C++ ?????
T.Tarmo.
|
|
|
|
|
What is the difference between C and C++? you say.
This is the problem. You do not know C and assume that C++ and C are the same.
1) In C, the OLE objects are called using the syntax:
Object->lpVtbl->Method(Object, ...)
This is done automatically in C++ by the compiler.
The code will compile perfectly when you use the C language using VC++ or lcc-win32 or any C compiler (not C++ compiler)
|
|
|
|
|
I would be very careful and think my arguments through at least twice before I told the author of a C compiler system that his C code is erroneous.
Compile it as C by naming the file "file.c" instead of "file.cpp".
LCC is really good for plain C Windows development, but I tend to like the C++ extra features added by a C++ compiler more, and therefore I mostly use VC++.
And I think I will use the proposed image ideas, although in my own lingua.
|
|
|
|
|
You do not seem to understand that C is not C++.
In C, reference parameters are explicitely passed by reference by adding the "&".
Please look at the header files.
I do not use the Microsoft compiler very often (and this is maybe the problem but I HAVE compiled my code with VC++ and it works pefectly of course. Use C, not C++ to compile it.
I did not know that "the lcc-win32 compiler it is irrevelant not matter how good it is"
This are just prejudices.
Please note:
C is NOT C++ and it is fully supported in the SDK.
If you do not believe me I can send you a working executable.
|
|
|
|
|
"I know nothing about the lcc-win32 compiler, but for most of the people on CodeProject, it is irrelevant, no matter how good it is."
Jacob Navia wrote:
I did not know that "the lcc-win32 compiler it is irrevelant not matter how good it is"
Well, although similar, you didn't get the point of the author of the original phrase. Look at the top of the page on top of your article. See that cute ET there? Now, read what's written near his right foot: "Your Visual Studio.NET Homepage"
That's why lcc-win32 is not relevant to most of us.
I see dumb people
|
|
|
|
|
Jacob Navia wrote:
I did not know that "the lcc-win32 compiler it is irrevelant not matter how good it is"
Others:
a) Look at the top of the page on top of your article. See that cute ET there? Now, read what's written near his right foot: "Your Visual Studio.NET Homepage"
b) lcc-win32 is not relevant to most of us.
Me:
The authors of "lcc", Fraser and Hanson, (A retargetable C compiler: design and implementation - Benjamin Cummings), are working in Microsoft (Both or only one, I do not konw exactly).
I Think that "pure fanatism" is deprecable.
Alfio Casella
|
|
|
|
|
alfcas wrote:
The authors of "lcc", Fraser and Hanson, (A retargetable C compiler: design and implementation - Benjamin Cummings), are working in Microsoft (Both or only one, I do not konw exactly).
I Think that "pure fanatism" is deprecable.
Good for them. And I hope they get better and better jobs.
But this does not increase most people's interest on lcc here. It's like going to a biking site and telling people "hey, sky-diving is a much better sport!".
I see dumb people
|
|
|
|
|
The Code Project home page also says:
Your place for 10,598 free C++, C# and .NET articles, code snippets, discussions, news and the best bunch of developers on the net
which is why I read it, although I haven't developed using MS tools for years.
I don't see why people need to be rude to each other, especially in a technical forum such as this, where ideas and other opinions are important.
Name-calling and unwillingness to see other people's points of view should remain in the school playground where they belong.
I certainly wouldn't relish working in a developer team where such hostility to others was shown.
|
|
|
|
|
I'm impressed.
You're arguing over a 3-year old topic.
|
|
|
|
|
OK, so I put your code in IPicture.c, which tells VC++ to compile it as C, not C++. I create IPicture.h, and include it in my dialog's cpp file. Result: 16 warnings:
Compiling...
IPicture.c
d:\misc\ipicturetest1\ipicture.c(72) : warning C4047: 'function' : 'unsigned int *' differs in levels of indirection from 'struct HPALETTE__ ** '
d:\misc\ipicturetest1\ipicture.c(72) : warning C4024: 'function through pointer' : different types for formal and actual parameter 2
d:\misc\ipicturetest1\ipicture.c(78) : warning C4047: 'function' : 'struct HDC__ *' differs in levels of indirection from 'struct HDC__ ** '
d:\misc\ipicturetest1\ipicture.c(78) : warning C4024: 'SelectPalette' : different types for formal and actual parameter 1
d:\misc\ipicturetest1\ipicture.c(79) : warning C4047: 'function' : 'struct HDC__ *' differs in levels of indirection from 'struct HDC__ ** '
d:\misc\ipicturetest1\ipicture.c(79) : warning C4024: 'RealizePalette' : different types for formal and actual parameter 1
d:\misc\ipicturetest1\ipicture.c(90) : warning C4047: 'function' : 'struct HDC__ *' differs in levels of indirection from 'struct HDC__ ** '
d:\misc\ipicturetest1\ipicture.c(90) : warning C4024: 'CreateCompatibleDC' : different types for formal and actual parameter 1
d:\misc\ipicturetest1\ipicture.c(91) : warning C4047: 'function' : 'struct HDC__ *' differs in levels of indirection from 'struct HDC__ ** '
d:\misc\ipicturetest1\ipicture.c(91) : warning C4024: 'CreateCompatibleBitmap' : different types for formal and actual parameter 1
d:\misc\ipicturetest1\ipicture.c(117) : warning C4047: 'function' : 'struct HDC__ *' differs in levels of indirection from 'struct HDC__ ** '
d:\misc\ipicturetest1\ipicture.c(117) : warning C4024: 'BitBlt' : different types for formal and actual parameter 1
d:\misc\ipicturetest1\ipicture.c(130) : warning C4047: 'function' : 'struct HDC__ *' differs in levels of indirection from 'struct HDC__ ** '
d:\misc\ipicturetest1\ipicture.c(130) : warning C4024: 'function through pointer' : different types for formal and actual parameter 2
d:\misc\ipicturetest1\ipicture.c(142) : warning C4047: 'function' : 'struct HDC__ *' differs in levels of indirection from 'struct HDC__ ** '
d:\misc\ipicturetest1\ipicture.c(142) : warning C4024: 'SelectPalette' : different types for formal and actual parameter 1
Linking...
IPictureTest1.exe - 0 error(s), 16 warning(s)
When I run it, I get a gray rectangle, no bitmap. I think the OP got it right - the code's broken, and the C/C++ differences have nothing to do with what's wrong. If you read the OP's comments point-by-point (and BTW, he was much more restrained than I would have been), you will have a roadmap of what bugs to fix. If you don't want to fix them, do everyone here a favor and remove this article. Too many people have wasted time on this already, and you just don't seem to get it.
|
|
|
|
|