|
I know that I can create from scratch the BITMAPINFOHEADER. Is it a matter of copying the information to the top of the Bitmap array?
|
|
|
|
|
alleyes wrote: Is it a matter of copying the information to the top of the Bitmap array?
If that's where you want it, yes.
You could also start with a pointer to where you want it
so you don't have to copy afterwards...
BITMAPINFOHEADER *pbmiHeader = (BITMAPINFOHEADER *)GlobalLock(myhglobal);
pbmiHeader->biSize = sizeof(BITMAPINFOHEADER);
etc...
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Mark Salsbery wrote: If that's where you want it, yes.
Well actually the file header will be at top but I get it.
Mark Salsbery wrote: BITMAPINFOHEADER *pbmiHeader = (BITMAPINFOHEADER *)GlobalLock(myhglobal);
pbmiHeader->biSize = sizeof(BITMAPINFOHEADER);
That's helpful...
|
|
|
|
|
After searching on the internet, the possible solution that come out is by using TabPage.DrawToBitmap, put the bitmap in a PictureBox, set the position of PictureBox to the same location of TabPage, and fade it. The code is below :
System::Void tabControl1_SelectedIndexChanged(System::Object^ sender, System::EventArgs^ e)
{
alphaBlend = 250;
repaint = true;
TabPictureBox->Visible = true;
int posX = tabControl1->Location.X + tabControl1->TabPages[tabControl1->SelectedIndex]->Margin.Left + 1;
int posY = tabControl1->Location.Y + tabControl1->ItemSize.Height + 1 +
tabControl1->TabPages[tabControl1->SelectedIndex]->Margin.Top;
TabPictureBox->Location = System::Drawing::Point(posX, posY);
TabPictureBox->Size = tabControl1->TabPages[tabControl1->SelectedIndex]->Size;
TabBitmap = gcnew Bitmap(tabControl1->TabPages[tabControl1->SelectedIndex]->Width,
tabControl1->TabPages[tabControl1->SelectedIndex]->Height);
tabControl1->TabPages[tabControl1->SelectedIndex]->DrawToBitmap(TabBitmap,
Rectangle(0, 0, tabControl1->TabPages[tabControl1->SelectedIndex]->Width,
tabControl1->TabPages[tabControl1->SelectedIndex]->Height));
while (alphaBlend > 0)
{
alphaBlend = alphaBlend - 25;
TabPictureBox->Refresh();
}
TabPictureBox->Visible = false;
repaint = false;
}
System::Void TabPictureBox_Paint(System::Object^ sender, System::Windows::Forms::PaintEventArgs^ e)
{
if (repaint)
{
if (TabBitmap != nullptr)
{
Bitmap^ temp = gcnew Bitmap(TabBitmap);
Graphics^ bitmapGraphics = Graphics::FromImage(temp);
if (alphaBlend < 0) alphaBlend = 0;
SolidBrush^ greyBrush = gcnew SolidBrush(Color::FromArgb(alphaBlend, Color::White));
bitmapGraphics->CompositingMode = CompositingMode::SourceOver;
bitmapGraphics->FillRectangle(greyBrush, Rectangle(0, 0, TabBitmap->Width, TabBitmap->Height));
e->Graphics->CompositingQuality = CompositingQuality::GammaCorrected;
e->Graphics->DrawImage(temp, 0, 0);
}
}
}
The problem is that each time I select the tabPage, my CPU usage spike to 70 - 80% and the fading effect is kind of slow. Is there any solution to fix it so that I can draw the bitmap faster and with minimum CPU usage (less than 50%)?
Thanks.
|
|
|
|
|
I need a program in PHP which can extract the hidden biders from ebay.I will have to insert the item number and the program must show me all bidders of the auction and their emails.
Also the same program must extract the registered contact information for any specified bidder specially the email address
I will pay for this
If someone can help please contact me at totos_back@yahoo.com
Thanks
|
|
|
|
|
In an app that is used to capture images, the information used to store the image data is referenced by a pointer to HGLOBAL. That is then used to re-create the image so it can be written to disk with a call to GlobalFree.
I have two problems:
I need to attach a file header so I can write the image to a file.
The image data is of native type DWORD so I cant use the .NET classes without massaging the image data.
What I have done thus far:
BITMAPINFOHEADER* imgHeader = (BITMAPINFOHEADER*)GlobalLock(gPtrImage);
array<BYTE>^ imgArray = gcnew array<BYTE>(imgHeader->biSizeImage);
if (!imgHeader)
{
GlobalFree(gPtrImage);
return;
}
BITMAPFILEHEADER* bfh = new BITMAPFILEHEADER();
bfh->bfType = 0x4d42; //BM
bfh->bfSize = (DWORD) (sizeof(BITMAPFILEHEADER) + imgHeader->biSize + imgHeader->biSizeImage);
bfh->bfReserved1 = 0;
bfh->bfReserved2 = 0;
bfh->bfOffBits = (DWORD) (bfh->bfSize - imgHeader->biSizeImage);
LPDWORD Pixels = (LPDWORD)((LPBYTE)imgHeader + sizeof(BITMAPINFOHEADER));
Marshal::Copy(static_cast<IntPtr>(bfh), imgArray, 0, sizeof(BITMAPFILEHEADER));
Marshal::Copy(static_cast<IntPtr>(Pixels), imgArray, (sizeof(BITMAPFILEHEADER) + 1), imgHeader->biSizeImage);
GlobalUnlock(gPtrImage);
System::Environment::SpecialFolder saveFolder = System::Environment::SpecialFolder::MyDocuments;
SaveFileDialog^ sfd = gcnew SaveFileDialog();
sfd->InitialDirectory = System::Environment::GetFolderPath(saveFolder);
sfd->Filter = "Device Independent Bitmaps |*.bmp|All files|*.*";
if (sfd->ShowDialog() == System::Windows::Forms::DialogResult::OK)
{
System::IO::Stream^ imgFileStream = sfd->OpenFile();
if (imgFileStream != nullptr)
{
imgFileStream->Write(imgArray, 0, imgArray->Length);
imgFileStream->Close();
}
}
GlobalFree(gPtrImage);
gPtrImage = NULL;
The file size is a lot larger than I would expect for a 640*480 32 bit BMP and it can't be displayed.
The image is fine when written to a picturebox, the data is then unlocked but NOT freed. As a test, I save the image of the picturebox i.e PictureBox->Image and that is fine. The data needs to to be handed off to another application that requires native code so I need to re-create the image from the pointer to HGLOBAL and that's where it falls down
What might be wrong with this?
Thanks for any help
|
|
|
|
|
BITMAPINFOHEADER.biSizeImage is allowed to be 0...
I would personally feel better about checking for that unless
you know for sure it's never going to be 0...maybe something like
if (imgHeader->biSizeImage == 0)
imgHeader->biSizeImage = (((imgHeader->biWidth * (long)imgHeader->biBitCount + 31L) & (~31L)) / 8L) * abs(imgHeader->biHeight);
Al_S wrote: array<BYTE>^ imgArray = gcnew array<BYTE>(imgHeader->biSizeImage);
Your array isn't big enough. What about the size of the
BITMAPFILEHEADER and the BITMAPINFOHEADER?
Al_S wrote: Marshal::Copy(static_cast<intptr>(Pixels), imgArray, (sizeof(BITMAPFILEHEADER) + 1), imgHeader->biSizeImage);
Array indexes are 0-based... That should be
Marshal::Copy(static_cast<intptr>(Pixels), imgArray, sizeof(BITMAPFILEHEADER), imgHeader->biSizeImage);
Also I'm not sure about those static_casts... why not just use IntPtr(bfh)/IntPtr(Pixels)
Al_S wrote: The file size is a lot larger than I would expect for a 640*480 32 bit BMP
Should be a little over 1MB - just how big is it? You're the one
calculating the size - what do you see in the debugger?
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Hi Mark.
Since the original image is from a global pointer to HGLOBAL, which was previously created and displayed, I am aware of all the fields of the BITMAPINFOHEADER. They are all set from grabbing an image in other code. I am trying to re-create the image after handing off the pointer to HGLOBAL elsewhere
With that:
biSizeImage = 0x12c000 (about 1.2M)
biBitCount = 0x20
...
...
I saw that the array size was goofy so I fixed that - I think.
array<byte>^ imgArray = gcnew array<byte>(imgHeader->biSizeImage + sizeof(BITMAPFILEHEADER));
I also fixed copying to the array:
Marshal::Copy(static_cast<IntPtr>(bfh), imgArray, 0, sizeof(BITMAPFILEHEADER));
Marshal::Copy(static_cast<IntPtr>(Pixels), imgArray, sizeof(BITMAPFILEHEADER), imgHeader->biSizeImage);
All this washes out to a correct file size.
When viewed in a hex editor, the BITMAPFILEHEADER appears where it belongs correctly. The rest of the data is different though. The resultant image can not be viewed
As far as the use of the static_cast, I don't have any problems with that and I think I've used it properly.
Thanks for responding.
|
|
|
|
|
alleyes wrote: I saw that the array size was goofy so I fixed that - I think.
array^ imgArray = gcnew array<BYTE>(imgHeader->biSizeImage + sizeof(BITMAPFILEHEADER));
Still not big enough
array<BYTE>^ imgArray = gcnew array<BYTE>(imgHeader->biSizeImage + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER));
alleyes wrote: Marshal::Copy(static_cast<IntPtr>(Pixels), imgArray, sizeof(BITMAPFILEHEADER), imgHeader->biSizeImage);
You're not writing the BITMAPINFOHEADER to the output array...
I missed that one the first time, sorry
Marshal::Copy(static_cast<IntPtr>(imgHeader), imgArray, sizeof(BITMAPFILEHEADER), sizeof(BITMAPINFOHEADER) + imgHeader->biSizeImage);
Mark Salsbery
Microsoft MVP - Visual C++
modified on Tuesday, January 12, 2010 4:47 PM
|
|
|
|
|
array size change plus the proper copy nails it.
Thanks very much!
|
|
|
|
|
Hi Mark,
Is there a way to do the reverse of this?
That is, one HGLOBAL to store different images, where it normally is one HGLOBAL relating to one image.
Thanks for the valuable help!
|
|
|
|
|
Hi Developers.
i am going to wrap lib(static library ) file in c++. one function return HGLOBAL DIB. how can i access Byte Array or Bitmap Image from this and pass this Byte Array or bitmap to My C# Project.
please help me.
thanks in advance.
Here is function that return HGLOBAL DIB Type.
<pre lang="c++"> HGLOBAL m_hDib;
int retval = XRaySensorIsImageAvailable();
if ( 0 < retval )
{
if (m_hDib ) ::GlobalFree(m_hDib);
m_hDib = XRaySensorGetDIB();
}
|
|
|
|
|
Hi
How can i get the screen width and height in Managed C++/CLI? I have used
Screen^ screen = gcnew Screen::PrimaryScreen;
But its not working.
Thanks
|
|
|
|
|
Within the Screen class, PrimaryScreen is a property, not a constructor. So you don't need gcnew
FYI1: "its not working" is not informative; if there is an error or exception, best is to show us the message.
FYI2: all this is explained in the documentation. Maybe it would be wise to study an introductory book when getting acquainted to a new technology or language.
|
|
|
|
|
Easy at it's:
int monitor_height=Screen::PrimaryScreen->Bounds.Height;
int monitor_width=Screen::PrimaryScreen->Bounds.Width;
|
|
|
|
|
I just recently posted a question very similar to this(System::String ^ to LPCVOID conversion?), it was answered but I still must be missing something.
In this case I need a LPCWSTR. What I've tried should be evident in the following:
......
char* pProcName = (char*)(void*)Marshal::StringToHGlobalAnsi(this->ProcName->Text);
LPCWSTR pProcName2 = (LPCWSTR)(void*)Marshal::StringToHGlobalAnsi(this->ProcName->Text);
LPCWSTR test2 = (LPCWSTR) pProcName;
HWND windowHandle = FindWindowW(NULL, (LPCWSTR) pProcName);
if (windowHandle)
MessageBox::Show("SUCCESS");
........
I guess one option is to convert a char* to wchar_t*?
If somehow I could make the conversion correctly, uhg. I really just need someone who knows whats up to point it out to me lol...
|
|
|
|
|
According to the MSDN Documentation[^] StringToHGlobalAnsi() returns a char* , i.e. a pointer to ASCII characters. In order to use this as wide characters you will need to do a string conversion, you cannot just cast it and expect it to work. Use mbtowc() or similar to convert from ASCII to wide characters.
|
|
|
|
|
Yea, I didnt expect it to work. But when you have no other ideas... lol thanks man! Ill give it a go!
|
|
|
|
|
Mattzimmerer wrote: Yea, I didnt expect it to work.
That suggests you would be well advised to spend some time learning what casts are all about. Remember that all the answers are somewhere in MSDN. I know it's not the easiest site to navigate, but the new Bing search is pretty good; it's where I found your answer!
|
|
|
|
|
Mattzimmerer wrote: I guess one option is to convert a char* to wchar_t*?
Why use StringToHGlobalAnsi if you don't want an ANSI string?
Maybe try StringToHGlobalUni.
And don't forget to free the allocated memory when you're done with it!
Since you're wanting wide chars, you also can use PtrToStringChars
(from vcclr.h).
Mattzimmerer wrote: need someone who knows whats up to point it out to me
The documentation knows what's up!
A bunch of interop examples[^] including How to: Access Characters in a System::String[^]
Calling Native Functions from Managed Code[^]
Mark Salsbery
Microsoft MVP - Visual C++
modified on Thursday, January 7, 2010 3:42 PM
|
|
|
|
|
Okay, you guys were a ton of help, but there is still something I am missing. Why dont I just show you what I am trying to do:
I am trying to get a name from a windows forms textbox converted so that I can use it in FindWindowW() so that I can send a PID out to a driver
this code is pretty messy atm, I usually clean it up after I get the proper way to do something. (imo lol)
char* pProcName = (char*)(void*)Marshal::StringToHGlobalUni(this->ProcName->Text);
wchar_t ProcNameWSTR, *pProcNameWSTR = &ProcNameWSTR;
const wchar_t tester[11] = L"Calculator";
int lengthmbc = mbtowc(pProcNameWSTR,pProcName,sizeof pProcName);
unsigned long Returned;
input bInput;
bInput.bytestoread;
bInput.processid;
bInput.startaddress;
HWND windowHandle = FindWindowW(NULL, pProcNameWSTR);
HWND windowHandle2 = FindWindowW(NULL, (LPCWSTR) &tester);
if (windowHandle)
MessageBox::Show("pProcNameWSTR success");
if (windowHandle2)
MessageBox::Show("tester wchar_t success");
DWORD* processID = new DWORD;
GetWindowThreadProcessId(windowHandle, processID);
DeviceIoControl(
hFile,
IOCTL_MZ_READMEMORY,
(LPVOID) &bInput,
sizeof bInput,
NULL,
0,
&Returned,
(LPOVERLAPPED) NULL);
the problem is that I cannot get the contents of ProcNameWSTR to match my tester[11] (the first if check fails and the second succeeds) any insight?
|
|
|
|
|
Mattzimmerer wrote: I cannot get the contents of ProcNameWSTR to match my tester[11]
ProcNameWSTR is a single wchar_t, so isn't very useful here.
Plus you don't even use it anywhere.
Marshal::StringToHGlobalUni returns a const pointer to a wchar_t
string, so casting it to a char* then converting it to a wchar_t
string isnt' going to work.
Try:
const wchar_t *pProcNameWSTR = (const wchar_t *)(void *)Marshal::StringToHGlobalUni(this->ProcName->Text);
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
worked great thank you. You know, I tried something like this, I just didnt make it a const, perhaps thats the reason it didnt work... Either that or I threw in some ANSII.. o well thanks man!
|
|
|
|
|
HI
I have DataTable n there is 5 column I had created
I want to get 5 column name and column data type from my datatable to create slq query
"Create Table mytable ([from datatable column name and type 1 to 5 ])"
how to do it ???
thanks
modified on Thursday, January 7, 2010 12:24 AM
|
|
|
|
|
First of all this doesn't sound like a good question
all you are asking is really simple to do, too simple to ask in this forum. Maybe it would be good for you to study an introductory book to this language
i didn't get you real problem but here some hint....
// to get the column number
dataGridView1->Columns->GetColumnCount
// to get the colum name (from column number i)
dataGridView1->Columns[i]->Name
// to get the column value type (from column number i)
dataGridView1->Columns[i]->ValueType
|
|
|
|