|
Anthony Appleyard wrote: how can I check if the read failed?
using namespace Gdiplus;
...
Bitmap MyBitmap(L"C:\\some.jpg");
if (Ok != MyBitmap.GetLastStatus())
{
}
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Thanks for your help here.
However, the function as it now stands (without text which I commented out to track the bug down)) is:
short jpgread (image&I,char*filename){
int i,n=strlen(filename),CurY; WCHAR fn[600];
for(i=0;i<=n;i++) fn[i]=filename[i];
using namespace Gdiplus;
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
Bitmap MyBitmap(fn);
GdiplusShutdown(gdiplusToken);
return 1;}
which causes
Unhandled exception at 0x73826a6a in ppp_vc.exe: 0xC0000005: Access violation reading location 0x011b227c.
in the function
inline Image::~Image() { DllExports::GdipDisposeImage(nativeImage);}
in GdiPlusBitmap.h
The stack frame dropdown says that this was called by
Gdiplus:Image::~Image() (line 92), which was called by
Gdiplus:Bitmap::Bitmap() + 0x2b bytes, which was called by
the jpgread() shown here.
I was compiling in the mode "align struct elements on multiples of 1".
-------------------
If I remove the line
Bitmap MyBitmap(fn);
the function runs through without error-exiting (but does nothing useful).
I inserted statements giving values to the elements of the struct gdiplusStartupInput, but it still error-exited in Image::~Image().
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Please also, how can I put an existing HBITMAPINFO and HBIPMAP into a `class Image' or `class Bitmap' and then output it to a JPG file?
<div class="ForumMod">modified on Saturday, December 22, 2007 5:58:56 AM</div>
|
|
|
|
|
Anthony Appleyard wrote: for(i=0;i<=n;i++) fn[i]=filename[i];
I'm not sure how you got that to compile, but you
need to actually convert the char string to a
WCHAR string before passing it to the constructor.
One way is with the ATL string conversion macros....
#include <AtlConv.h>
...
using namespace Gdiplus;
...
short jpgread (image&I, char*filename)
{
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
CA2W wcharfilename(filename);
Bitmap MyBitmap(wcharfilename);
GdiplusShutdown(gdiplusToken);
return 1;
}
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
GdiplusShutdown must be called out of scope of the Bitmap object.
The Unhandled exception arise because the GdiplusShutdown function is called
before the Bitmap object is destructed.So define Bitmap object within { }.
<br />
short jpgread (image&I, char*filename)<br />
{<br />
<br />
GdiplusStartupInput gdiplusStartupInput;<br />
ULONG_PTR gdiplusToken;<br />
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);<br />
{<br />
CA2W wcharfilename(filename);<br />
<br />
Bitmap MyBitmap(wcharfilename);<br />
}
GdiplusShutdown(gdiplusToken);<br />
return 1;<br />
}<br />
<br />
|
|
|
|
|
Graphis g;
Rect rt;
...
g.TransformPoints(CoordinateSpaceWorld,CoordinateSpacePage,(Point*)&rt,2);
BTW the way, for example, there are two ways to do invalidate:
a. Invalide(FALSE)
b. Calculate a rect to invalidate(calc bound box including a bound box of a rotated rect, and do Rect::Union about 3 times, and with some if...else...),and do InvalidateRect
In OnDraw, only copy a memory Grahpics to the screen.
Which is more efficient?
|
|
|
|
|
followait wrote: Why does the trick fail, one Rect to two Points
Maybe because a Gdiplus::Rect is a point and a size, not two points.
followait wrote: Which is more efficient?
I'm not sure what you're asking. The less pixels rendered to the screen,
the more efficient drawing will be. Unless your calculated rect is always
close to the size of the entire window, using method b should always be more
efficient.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
about the invaliate question
Because it is a little complex to calculated the rectangle, which needs to be redrawn, also the code became less clear. Here is a sample code:
Rect rt;
if (m_pCtrlBoxSizing) {
m_pCtrlBoxSizing->GetBoundRect(&rt);
} else if (m_pCtrlBoxRotating) {
m_pCtrlBoxRotating->GetBoundRect(&rt);
} else if (m_pCtrlBoxMoving) {
m_pCtrlBoxMoving->GetBoundRect(&rt);
}
Rect::Union(rt,rt,m_HotRt);
InvalidateRect(&CRect(rt.GetLeft(),
rt.GetTop(),
rt.GetRight(),
rt.GetBottom()),FALSE);
or with a simple line
Invalidate(FALSE);
In OnDraw, there is only a bitblt
|
|
|
|
|
Only you can decide what's more important - clear code or
performance. +-10 simple lines of code isn't all that unclear
IMO
Of course, at some point, calculating an update region could
take longer than drawing all the pixels. That's application
specific - you'll have to determine that.
I personally have always got better performance by using update
rects/regions over full redraws. That's in my applications.
Cheers,
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Any way to make it more clear?
|
|
|
|
|
|
For getting the user name in, we are call the GetUserName() in the Application context, in which case we get it right if the Application is launched form logged in user.
But in case of system process GetUserName() return "SYSTEM" as current user.
There is any API or Method to get the current user name in system process?
THANKS IN ADVANCE
|
|
|
|
|
Look at regestry
key
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer
value
Logon User Name
|
|
|
|
|
the value at HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer
a
|
|
|
|
|
myshketer wrote: HKEY_CURRENT_USER
How will that work from a service running as a different "user"?
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
For systems with fast user switching (XP+) where more than one user
can be logged on at the same time, maybe something like this:
#include <WtsApi32.h>
...
DWORD dwSessionId = WTSGetActiveConsoleSessionId();
if (0xFFFFFFFF != dwSessionId)
{
LPTSTR pUserNameStr = 0;
DWORD dwBytesReturned = 0;
if (WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, dwSessionId, WTSUserName, &pUserNameStr, &dwBytesReturned))
{
WTSFreeMemory(pUserNameStr);
}
}
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Go to: project, project property, C/C++, Code Generation, Struct Member Alignment: that gives an option to align all the struct elements on multiples of 1 or 2 or 4 or 8 or 16. Choose 1.
|
|
|
|
|
If you find that doesn't work for your whole project then you can set the alignment on individual types see here[^]. Setting global alignment to 1 may also cause performance issues, problems with calling certain APIs and the effects on COM are probably beyond my comprehension. Microsoft pretty universally assume that alignment will be 8 as that's the default for all MS Compilers since the dark ages so you may even have trouble calling stuff in the runtime with global 1 alignment.
Hey if software development was that easy everyone would be doing it
Nothing is exactly what it seems but everything with seems can be unpicked.
|
|
|
|
|
Matthew Faithfull wrote: Hey if software development was that easy everyone would be doing it
Indeed everyone is doing it, don't you read the posts?
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
[my articles]
|
|
|
|
|
CPallini wrote: don't you read the posts?
No I take a random stab at what the question might by reading every second word of the title and then post a reply consisting of artfully rearranged phrases from one of 16 stock replies written for me by a team of genuine Irish code pixies I met in bar in Edinburough. It really saves a lot of time and effort and people seem to like it.
Nothing is exactly what it seems but everything with seems can be unpicked.
|
|
|
|
|
That must be one of the best of the stock
PS: My regards to such a lovely town.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
[my articles]
|
|
|
|
|
That being generally a bad idea aside, didn't someone mention
that here[^] yesterday?
Good luck!
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Hello everyone,
Suppose I have some objects created on local function stack (not on heap). And I allocate and free all the related resources in the constructor and destructor (e.g. memory and file handles). And I do not implement explicit exception handling code in the function for resource free purpose, and simply rely on destructor to free resources if exception occurs, that is,
1. when exception occurs and the exception triggers us to go out of current function stack to the caller to find exception handlers;
2. since objects are allocated on local stack, when exception triggers us to go out of current stack to its caller to find exception handler, the lifecycle of local objects on local stack will expire, and its related destructor will be invoked and free resources.
Pseudo code like this,
void func()
{
Class1 inst1;
Class2 inst2;
...
return;
}
Does above code always safe? Are there any potential risks to leak resources?
thanks in advance,
George
|
|
|
|
|
Yes, that's as safe as you make Class1 and Class2 except in one instance, a stack overflow. In all other cases I know of, provided you have an exception handler somewhere up the stack then the Unwind function will be called in the runtime which uses a bit of compiler magic to ensure that the destructors for inst1 and inst2 are called. In the case of a stack overflow exception you're pretty much dead in the water. There is the _resetstkoflw() runtime function but it won't prevent anything allocated on the heap in your Class1 and Class2 constructors being leaked.
Nothing is exactly what it seems but everything with seems can be unpicked.
|
|
|
|
|
In general, what the thread does is: Creating and sending an e-mail containing a file attachment using an Outlook or Lotus Notes client (if installed on the system).
Running the thread once always works fine, and it terminates correctly. However, when i try to run it for a second time, it throws an exception in MFC42.DLL, unfortunately not always at the same code line, but more or less randomly, esp. during manual debugging:
UINT CommonSendMailThread(LPVOID pParam)<br />
{<br />
<br />
if (sType == "%OUTLOOK%") {<br />
try { <br />
_DApplication OutlookHandle; <br />
<br />
if (!AfxOleInit())<br />
return 1;<br />
else {
if (OutlookHandle.CreateDispatch("Outlook.Application.8") == FALSE) {<br />
if (OutlookHandle.CreateDispatch("Outlook.Application.9") == FALSE) {<br />
if (OutlookHandle.CreateDispatch("Outlook.Application.10") == FALSE) {<br />
if (OutlookHandle.CreateDispatch("Outlook.Application.11") == FALSE) {<br />
if (OutlookHandle.CreateDispatch("Outlook.Application.12") == FALSE) {<br />
return 1;<br />
}}}}}}<br />
<br />
_DMailItem newMail;<br />
<br />
newMail = OutlookHandle.CreateItem(0);<br />
<br />
<br />
newMail.Send();<br />
<br />
OutlookHandle.ReleaseDispatch();<br />
}<br />
<br />
catch(...) {<br />
return 1;<br />
}<br />
}
<br />
else if (sType == "%NOTES%") {<br />
try {<br />
if (!AfxOleInit())<br />
return 1;<br />
<br />
NOTESSESSION *pNotesSes = NULL;<br />
NOTESDATABASE *pNotesDB = NULL;<br />
NOTESDOCUMENT *pNotesDoc = NULL;<br />
NOTESRICHTEXTITEM *pNotesRichTextItem = NULL;<br />
<br />
pNotesSes = new NOTESSESSION;<br />
<br />
if ( !pNotesSes )<br />
return 1;<br />
<br />
if ( pNotesSes == NULL )<br />
return 1;<br />
<br />
if (!pNotesSes -> CreateDispatch( "Notes.NotesSession" ))<br />
return 1;<br />
<br />
if ( pNotesSes -> m_lpDispatch == NULL ) { <br />
delete pNotesSes;<br />
return 1;<br />
}<br />
<br />
<br />
pNotesDoc ->SEND(0, COleVariant(sRecipientAddress));<br />
pNotesDoc ->REMOVE (0);<br />
<br />
pNotesRichTextItem ->ReleaseDispatch();<br />
pNotesDoc ->ReleaseDispatch();<br />
pNotesDB ->ReleaseDispatch();<br />
pNotesSes ->ReleaseDispatch();<br />
<br />
delete pNotesRichTextItem;<br />
delete pNotesDoc;<br />
delete pNotesDB;<br />
delete pNotesSes;<br />
}<br />
<br />
catch(...) {<br />
return 1;<br />
}<br />
}
else {<br />
return 1;<br />
}<br />
<br />
return 0;<br />
}
I'm totally confused and have no idea how to solve or even access the problem. Any hint or help is greatly appreciated!
|
|
|
|
|
Member 4760200 wrote: In general, what the thread does is: Creating and sending an e-mail containing a file attachment using an Outlook or Lotus Notes client (if installed on the system).
Running the thread once always works fine, and it terminates correctly. However, when i try to run it for a second time, it throws an exception in MFC42.DLL, unfortunately not always at the same code line, but more or less randomly, esp. during manual debugging:
I would look up the MFC implementation of the send mail command in CDocument, and adapt the code to my purposes, rather than sending it through Outlook or Lotus Notes. If I did need to do it that way, one of the first questions I'd ask is "What exception is being thrown?" Also, in general returning 1 is not adequate for handling unknown exceptions. Terminating the whole program is more reasonable. Finally, the random nature of the exception sounds like a race condition, and since it doesn't go away when you debug, I would guess that you are calling functions that are intended to be called from only one thread for the duration of the process. I'm sorry I can't be more helpful.
Nathan
|
|
|
|