|
I am currently trying to get the bitarray of bitmap that has already been loaded into a picture box of a dialog window when I press a button on the dialog.
The overall aim is, Button 1 takes data from user, takes editing parameters and creates a BMP from it the result of the editing , putting the BMP into a picture box in a dialog. Button 2 is the "save" feature, which allows the final changed Bitmap to be saved back into bitmapbits array.
Here's the problem:
void CProjectDlg::OnButton2Press()
{
CFile TestFile;
HBITMAP CapturedBMP = m_PicBox.GetBitmap();
CBitmap RS232BMP;
RS232BMP.Attach(CapturedBMP);
BITMAP TempBMStore;
RS232BMP.GetBitmap(&TempBMStore);
BYTE* bmpBuffer=(BYTE*)GlobalAlloc(GPTR, TempBMStore.bmWidthBytes*TempBMStore.bmHeight);
DWORD dwValue=RS232BMP.GetBitmapBits(TempBMStore.bmWidthBytes*TempBMStore.bmHeight, bmpBuffer);
}
I get a valid handle at (1) but I my TempBMStore is blank after I execute line (2), meaning I do not have a valid Bitmap or something (return value is 0). What Am I doing wrong here?
When I cut and paste this code into the section of code that originally places the bitmap into the picture box, I have absolutely no problem. ie:
void CProjectDlg::OnButton1Press()
{
.
.
.
<get data="" from="" user="">
.
.
.
<edit the="" bitmap="" bit="" values="">
.
.
.
m_PicBox.SetBitmap(TmpBmp);
CFile TestFile;
HBITMAP CapturedBMP = m_PicBox.GetBitmap();
CBitmap RS232BMP;
RS232BMP.Attach(CapturedBMP);
BITMAP TempBMStore;
RS232BMP.GetBitmap(&TempBMStore);
BYTE* bmpBuffer=(BYTE*)GlobalAlloc(GPTR, TempBMStore.bmWidthBytes*TempBMStore.bmHeight);
DWORD dwValue=RS232BMP.GetBitmapBits(TempBMStore.bmWidthBytes*TempBMStore.bmHeight, bmpBuffer);
}<pre>
Thje return for line (2) is valid and I can get the bitmap bits with no errors. Same code, different behaviour. Do I need to make the Picture Box valid or something?
Thanks in advance
|
|
|
|
|
Is it possible that TmpBmp in your OnButton1Press is a local variable and when the method returns it destroys the bitmap so when you later try to access it you get an invalid handle? (CBitmap's destructor destroys the bitmap associated with it)
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
|
|
|
|
|
Never thought of it that way. Thought the Picture box would store the data so I can retrieve it later or allow another function to operate on it.
If the data object is destroyed like that, all my functions would have to be tightly coupled together. and that would be rather wierd from an OO programming POV.
You have anyway to retrieve a bitmap from a picture box object in a dialog AFTER the function that places it there destroys the CDC that was containing it?
Jeffrey
|
|
|
|
|
Well, make your CBitmap a member variable of your dialog class, then the bitmap will be existent while your dialog is up, or you could use the Detach method to "disconnect" the CBitmap and the HBITMAP but i don't know if the image control is possible to destroy the bitmap for you, pay attention or you could leak GDI resources.
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
|
|
|
|
|
Dear all,
How can I tell c++ to allocate memory from Physical RAM, not virtual memory (on WinXP).
Thanks in advance,
Regards
|
|
|
|
|
Can you more explain what do you need exatcly?
Of one Essence is the human race
thus has Creation put the base
One Limb impacted is sufficient
For all Others to feel the Mace
(Saadi )
|
|
|
|
|
|
Thanks a lot 4 ur excellent answer .
|
|
|
|
|
what is the meaning of '?'and ':' in this expression?
bool Addr
int m= Addr ? 1 : 5
thanks
|
|
|
|
|
means:
int m;
if (Addr)
{
m = 1;
}
else
{
m = 5;
}
check Addr (? -> check)
if its true use first expression (1)
else use second one (5)
|
|
|
|
|
X1 ? answer1 : answer2
If X1 is true the expression will return answer1, if it is not it will return answer2 and I think you are new so see C++ Reference[^].
Of one Essence is the human race
thus has Creation put the base
One Limb impacted is sufficient
For all Others to feel the Mace
(Saadi )
|
|
|
|
|
This line of code first evaluates the condition 'Addr == true'.
Then, if the condition is true assigns 1 to m, otherwise asssigns 5 to it.
|
|
|
|
|
the ?: is a ternary operator(takes three operands), which is known as Conditional Operator. Its the simplified form of a simple if statement. Check the MSDN Link[^] for more info.
Regards,
Jijo.
_____________________________________________________
http://weseetips.com[ ^] Visual C++ tips and tricks. Updated daily.
|
|
|
|
|
It actually means you need a good C tutorial.
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.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
How to calculate inverse of a matrix, i am using vc++ 6.0 ,
|
|
|
|
|
I'll guess you may have to write a program to do that, without regards to what version of Visual C++ you are using.
A little more clarity on your query, may be?
It is a crappy thing, but it's life -^ Carlo Pallini
|
|
|
|
|
Well, homeworks are meant to be done by your brain, not by codeproject. Refer this code snippet[^] and try to write by your own. Hope it helps!
Regards,
Jijo.
_____________________________________________________
http://weseetips.com[ ^] Visual C++ tips and tricks. Updated daily.
|
|
|
|
|
Numerical recipes in C book [^] may help.
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.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
Hey there,
I am using a CProgressBar to show the progress of several checksum operations. There are 3 of them, md5, sha1, and sha2, and they are done sequentially. I want to reset the progress bar just before each calculation, but I can't get the progress bar to redraw. Here is a snippet of what I am trying to do:
if(m_checksumPPage.isMD5Checked()) {
progbar.Invalidate();
progbar.UpdateWindow();
progbar.SetPos(0);
hash.domd5(progbar);// do the hash, which also updates the progbar to 100
}
if(m_checksumPPage.isSHA1Checked()) {
mprogbar.Invalidate();
progbar.UpdateWindow();
progbar.SetPos(0);
hash.dosha1(progbar);// do the hash, which also updates the progbar to 100
}
if(m_checksumPPage.isSHA256hecked()) {
progbar.SetPos(0);
progbar.Invalidate();
progbar.UpdateWindow();
hashsha2.do(progbar);
}
The hash.doxxx(progbar) methods will increment the progbar from 0 to 100 and leave it there when it finishes. The first time through it works fine, but the attempt to reset the progbar to zero for the second and third pass does not move the bar back to zero. I guess I am leaving out some sort of update message someplace, but I can't figure it out.
The progress bar is a CProgressCtrl and it is on a dialog box.
Any ideas?
Paul
|
|
|
|
|
Two out of three of your operations call SetPos after UpdateWindow().
I would start by calling SetPos() THEN invalidating/updating the window.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Thanks for the reply.
I have tried rearranging that code several different ways, along with trying to StepIt backwards to zero, resetting the range, and calling Invalidate/UpdateWindow on the entire dialog, as well as experimenting with overriding the main apps OnIdle to do continuous updates. Nothing has worked so far.
|
|
|
|
|
Either the operation is going faster than you can see it or you've
messed something up somewhere else.
This works for me on XP and Vista, from the UI thread with no
Invalidate/UpdateWindow necessary:
m_ProgressCtrl.SetRange(0,10);
for (int i = 0; i <= 10; i++)
{
m_ProgressCtrl.SetPos(i);
::Sleep(750);
}
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
The first operation works fine for me. Its the second and third that don't. Modify your snippet by copying/pasting it three times, and see if the pbar will reset to zero each time. That is the situation I am trying to fix.
I am glad you mentioned the speed thing. I checked that and verified it is not the speed. That would have been very dumb to miss.
|
|
|
|
|
This works here:
m_ProgressCtrl.SetRange(0,10);
for (int i = 0; i <= 10; i++)
{
m_ProgressCtrl.SetPos(i);
::Sleep(500);
}
for (int i = 0; i <= 10; i++)
{
m_ProgressCtrl.SetPos(i);
::Sleep(500);
}
for (int i = 0; i <= 10; i++)
{
m_ProgressCtrl.SetPos(i);
::Sleep(500);
}
I also tried range 0-1000 with no Sleep() call...
went so fast I couldn't see the second and third loops
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
This is interesting. I tried pasting your code in there, and it did work the way I want, resetting to zero each time. Playing around with the Sleep values, loop size and range, I get some funky update behaviors. If you experiment with this you might see what I mean. It seems as though there is some threshold at which the redrawing of the control can't keep up with the actual state of the control.
const int limit = 1000;
const int sleep = 3;
m_checksumProgressCtrl.SetRange(0,limit);
for (int i = 0; i <= limit; i++)
{
m_checksumProgressCtrl.SetPos(i);
::Sleep(sleep);
}
for (int i = 0; i <= limit; i++)
{
m_checksumProgressCtrl.SetPos(i);
::Sleep(sleep * 2);
}
for (int i = 0; i <= limit; i++)
{
m_checksumProgressCtrl.SetPos(i);
::Sleep(sleep * 4);
}
After this experiment I realize that I should probably do my checksum stuff in a separate thread. My test case was much too small to really reflect what I need to do, and the UI goes completely unresponsive during the loops (or the checksumming), which really won't work in the real world. I am going to have to rethink my approach. Thanks for the help, Mark.
|
|
|
|