|
|
What's the quickest way (in terms of programming time) to display an image (jpg, tif, bmp or gif) ? I thought about simply using a WebBrowser2 control, but wanted to ask here as imaging is something I've never got into so there might be a more accepted method of doing this.
Cheers,
Tom Archer
Inside C#, Extending MFC Applications with the .NET Framework
It's better to listen to others than to speak, because I already know what I'm going to say anyway. - friend of Jörgen Sigvardsson
|
|
|
|
|
Unless you want to study the JPEG file format and write a decoder by hand, you are better off using an image library.
I have had great results using the Victor Image Library. It is free for 30 days while you evaluate it.
It is available at:
http://www.catenary.com
The demo version of VIC32.DLL is available free for download. The commercial version of VIC32.DLL costs $499 and is included with any application that uses the VIC library. Although I would certainly pay for it if you planned on releasing software developed with it. If for whatever reason you didn't get the chance to fully evaluate it during the 30 days, (sday you got hit by a car and spent 29 days in the hospital) you could either change your system clock or do a web search for VIC32.DLL
|
|
|
|
|
No can do. This is for a chapter demo on reading BLOB data with ADO.NET. Therefore, I don't want to force the reader to have to download or install 3rd party products.
Cheers,
Tom Archer
Inside C#, Extending MFC Applications with the .NET Framework
It's better to listen to others than to speak, because I already know what I'm going to say anyway. - friend of Jörgen Sigvardsson
|
|
|
|
|
I forgot where I found this snippet.
You can use it in a subclassed CStatic you draw on the CDialog
in Sub Classed CStatic header
public:
void LoadPictureFile(LPCTSTR szFile);
virtual ~CSubClassStatic();
protected:
LPPICTURE gpPicture;
protected:
//{{AFX_MSG(CSubClassStatic)
afx_msg void OnPaint();
//}}AFX_MSG
in Sub Classed CStatic implementation File
#define MAX_LOADSTRING 100
#define HIMETRIC_INCH 2540
#define MAP_LOGHIM_TO_PIX(x,ppli) ( ((ppli)*(x) + HIMETRIC_INCH/2) / HIMETRIC_INCH )
void CSubClassStatic::OnPaint()
{
if (gpPicture)
{
CPaintDC dc(this); // device context for painting
// get width and height of picture
long hmWidth;
long hmHeight;
gpPicture->get_Width(&hmWidth);
gpPicture->get_Height(&hmHeight);
// convert himetric to pixels
int nWidth = MulDiv(hmWidth, GetDeviceCaps(dc.m_hDC, LOGPIXELSX), HIMETRIC_INCH);
int nHeight = MulDiv(hmHeight, GetDeviceCaps(dc.m_hDC, LOGPIXELSY), HIMETRIC_INCH);
RECT rc;
GetClientRect(&rc);
// display picture using IPicture::Render
gpPicture->Render(dc.m_hDC, 0, 0, nWidth, nHeight, 0, hmHeight, hmWidth, -hmHeight, &rc);
}
// TODO: Add your message handler code here
}
void CSubClassStatic::LoadPictureFile(LPCTSTR szFile)
{
// open file
HANDLE hFile = CreateFile(szFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE) return;
// get file size
DWORD dwFileSize = GetFileSize(hFile, NULL);
if (-1 == dwFileSize) return;
LPVOID pvData = NULL;
// alloc memory based on file size
HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, dwFileSize);
_ASSERTE(NULL != hGlobal);
pvData = GlobalLock(hGlobal);
_ASSERTE(NULL != pvData);
DWORD dwBytesRead = 0;
// read file and store in global memory
BOOL bRead = ReadFile(hFile, pvData, dwFileSize, &dwBytesRead, NULL);
_ASSERTE(FALSE != bRead);
GlobalUnlock(hGlobal);
CloseHandle(hFile);
LPSTREAM pstm = NULL;
// create IStream* from global memory
HRESULT hr = CreateStreamOnHGlobal(hGlobal, TRUE, &pstm);
_ASSERTE(SUCCEEDED(hr) && pstm);
// Create IPicture from image file
if (gpPicture)
gpPicture->Release();
hr = ::OleLoadPicture(pstm, dwFileSize, FALSE, IID_IPicture, (LPVOID *)&gpPicture);
_ASSERTE(SUCCEEDED(hr) && gpPicture);
pstm->Release();
if (gpPicture)
{
CPaintDC dc(this);
// get width and height of picture
long hmWidth;
long hmHeight;
gpPicture->get_Width(&hmWidth);
gpPicture->get_Height(&hmHeight);
// convert himetric to pixels
int nWidth = MulDiv(hmWidth, GetDeviceCaps(dc.m_hDC, LOGPIXELSX), HIMETRIC_INCH);
int nHeight = MulDiv(hmHeight, GetDeviceCaps(dc.m_hDC, LOGPIXELSY), HIMETRIC_INCH);
}
InvalidateRect(NULL, TRUE);
}
|
|
|
|
|
I kind of forgot what this actually was, it's using the (OLE I believe?), IPicture interface to load the file/type automatically
|
|
|
|
|
|
Use OleLoadPicturePath() to get an IPicture interface, then IPicture::Render() to draw it. You could also use the shell's IExtractImage interface to generate a thumbnail, but doing so takes about 30 lines of code.
--Mike--
"Big handwavy generalizations made from a position of deep ignorance is one of the biggest wastes of time on the net today.
-- Joel Spolsky
Ericahist | Homepage | RightClick-Encrypt | 1ClickPicGrabber
|
|
|
|
|
|
Either Michael's way, or using GDI+
Graphics g(hdc);
Image img(imageFileName);
g.DrawImage(x, y, &img);
Ryan "Punctuality is only a virtue for those who aren't smart enough to think of good excuses for being late" John Nichol "Point Of Impact"
|
|
|
|
|
I am developping application like photoshop
and have problem with making the title bar of dialog
boxes blue(just like when you activate dialog box,
but this time I want to make 2 or 3 dialog boxes
activated status). Any comments could be helpfull
Thank you in advance.
Shinya
|
|
|
|
|
|
Hey all,
I had a post on here about a week ago about executing code from memory instead of a PE file.
So far this is what I've done.
have this as the test code compiled
############################################
#include <stdio.h>
int main(int argc, char* argv[])
{
printf("Hello World!\n");
getc(stdin);
return 0;
}
compiled that and stored it as RCDATA resource 130 in my new project
############################################
this is the code I'm trying to execute it with, without writing it back to a file in my MFC dialog app
HRSRC hrInfo = FindResource(AfxGetResourceHandle(), MAKEINTRESOURCE(130), RT_RCDATA);
HGLOBAL hbytes = LoadResource(AfxGetResourceHandle(), hrInfo);
int (*ptr)(int argc, char *str[]);
ptr = (int (__cdecl *)(int, char *[]))hbytes;
int j = 1; char *strs;
(*ptr)(j, &strs);
CODE DONE
######################################
MODIFIED:
I also tried reallocating it with a FIXED flag, and it also didn't work
############ TRIED THIS TOO
HRSRC hrInfo = FindResource(AfxGetResourceHandle(), MAKEINTRESOURCE(130), RT_RCDATA);
HGLOBAL hbytes = LoadResource(AfxGetResourceHandle(), hrInfo);
int size = (UINT)SizeofResource(AfxGetResourceHandle(), hrInfo);
HGLOBAL pexec = GlobalReAlloc(hbytes, size, GMEM_FIXED);
int (*ptr)(int argc, char* argv[]);
ptr = (int (__cdecl *)(int, char *[]))pexec;
int j = 1; char *strs;
(*ptr)(j, &strs);
################
OK, the function I cast it to matches that of the main of the test code. BUT, it gives me an access violation. WHY? HGLOBAL DATA is supposed to be executable from memory without any special function right?, Will this work with the HGLOBAL as is, or do I need to explicitly GlobalAlloc it?
I realize that this may be an advanced topic, and I urge some people to refrain from replying as that my last post got a couple of very ignorant responses. Thanks for your understanding.
|
|
|
|
|
The topic is advanced, and using that kind of trickery requires skills and most importantly reason. I am not even going to discuss what possible reason you have to write code like this. Lets concentrate on what you actually trying to do:
Beer26 wrote:
HGLOBAL pexec = GlobalReAlloc(hbytes, size, GMEM_FIXED);
I am not completely sure what you expect from the statement above. I assume you want to create a copy of the resource in memory (I do not think GMEM_FIXED is going to be honored in Win32) You might be better off allocating new block of memory, insteadof realloc-ing something that you did not alloc-ed.
Beer26 wrote:
ptr = (int (__cdecl *)(int, char *[]))pexec;
I read the line above as - you assume that recourse you loaded is actually executable code of the function with signature "int (*ptr)(int argc, char* argv[]);" (please confirm). Are you sure that it is a valid executable code?
Beer26 wrote:
int j = 1; char *strs;
(*ptr)(j, &strs);
the line above actually try to execute the loaded code. (please confirm). Please note also that strs is not initialized.
How did you compile it? How did you put into resource? How are calls "getc" or "printf" going to be resolved ?
|
|
|
|
|
a) there is no guarantee that you have EXECUTE right on a HGLOBAL, but this doesn#t matter on Wintel Boxes
b) You *are+ aware that EXE files come a) with a PE header, and b) with a relocation table? They are not just "sequences of code bytes"...
"Der Geist des Kriegers ist erwacht / Ich hab die Macht" StS
sighist | Agile Programming | doxygen
|
|
|
|
|
"a) there is no guarantee that you have EXECUTE right on a HGLOBAL, but this doesn#t matter on Wintel Boxes"
From MSDN
"Remarks
If the heap does not contain sufficient free space to satisfy the request, GlobalAlloc returns NULL. Because NULL is used to indicate an error, virtual address zero is never allocated. It is, therefore, easy to detect the use of a NULL pointer.
Memory allocated with this function is guaranteed to be aligned on an 8-byte boundary. All memory is created with execute access; no special function is required to execute dynamically generated code. "
"b) You *are+ aware that EXE files come a) with a PE header, and b) with a relocation table? They are not just "sequences of code bytes"..."
Yes, I am. What if i write a small bit of code in ASM and only generate the OPCODE? Then try it with that? Would that work? I'm assuming it's not going to work with all the PE junk linked and compiled with it?
|
|
|
|
|
Beer26 wrote:
All memory is created with execute access;
Oops, sorry, I missed that (it's late over here ;-O )
b) yes that should work (as long as you refrain from absolute jumps/calls (or adress them correctly, with regards to the allocated base address)
If it doesn't, try to follow the thing in the debugger (disassembly window)
"Der Geist des Kriegers ist erwacht / Ich hab die Macht" StS
sighist | Agile Programming | doxygen
|
|
|
|
|
__asm
{
jmp (start of your code);
return;
}
|
|
|
|
|
woah, you gotta be kidding me, I'm going to try this now. It kind of makes sense too!
|
|
|
|
|
I'm including a class that has an inline function called
GetOldNodeIndex defined in the header file for that class.
When I try to access it, say in the main() function, the compiler
spills out (seemingly unrelated) unresolved symbol errors....
Here's the class definition
<code>
#if !defined(AFX_SPRINGNODE_H__7DC1CC9F_C211_478F_B542_9B71B4A3C4EA__INCLUDED_)
#define AFX_SPRINGNODE_H__7DC1CC9F_C211_478F_B542_9B71B4A3C4EA__INCLUDED_
#include "CM3DVector2f.h"
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
class CSpringNode
{
public:
unsigned int m_uiEntryTracker;
unsigned int m_uiNodeIndex;
unsigned int m_uiValence;
double m_dEnergy;
CM3DVector2f m_M3DPosition;
CSpringNode(unsigned int Index, CM3DVector2f& rPosition);
virtual ~CSpringNode();
bool operator<(const CSpringNode& rNode) const
{
return (m_dEnergy < rNode.m_dEnergy);
};
protected:
CSpringNode(){};
private:
unsigned int m_uiPreSortIndex;
public:
unsigned int GetOldNodeIndex() { return (m_uiPreSortIndex); };
};
#endif // !defined(AFX_SPRINGNODE_H__7DC1CC9F_C211_478F_B542_9B71B4A3C4EA__INCLUDED_)
</code>
and the main function
<code>
#include "stdafx.h"
#include "SpringNode.h"
#include "CM3DVector2f.h"
int main(int argc, char* argv[])
{
CM3DVector2f Vector;
Vector.x = 5.5;
Vector.y = -4.6;
CSpringNode aNode(0, Vector);
cout << aNode.GetOldNodeIndex() << endl;
return 0;
}
</code>
and the errors:
Compiling...
TrustRegion.cpp
Linking...
nafxcwd.lib(afxmem.obj) : error LNK2005: "void __cdecl operator delete(void *)" (??3@YAXPAX@Z) already defined in LIBCD.lib(dbgdel.obj)
nafxcwd.lib(thrdcore.obj) : error LNK2001: unresolved external symbol __endthreadex
nafxcwd.lib(thrdcore.obj) : error LNK2001: unresolved external symbol __beginthreadex
Debug/TrustRegion.exe : fatal error LNK1120: 2 unresolved externals
Error executing link.exe.
TrustRegion.exe - 4 error(s), 0 warning(s)
I should mention that if I remove everything that relates to the
inline function all those errors go away and everything works fine....
Anyone know what's going on here???
|
|
|
|
|
So if you comment out the cout << aNode.GetOldNodeIndex() << endl; line, all is well with the linker?
|
|
|
|
|
|
Then the next obvious question is what happens if you make the function non-inline?
|
|
|
|
|
The same thing. However, if I remove:
<br />
cout << temp << endl;<br />
cout << aNode.GetOldNodeIndex() << endl;<br />
<br />
it's okay.
|
|
|
|
|
Which implies that you cannot use any method of that class, inline or otherwise. Correct?
|
|
|
|
|