|
1. Get dimensions of existing HBITMAP
2. Use CreateDIBSection to create an image of the correct size
3. Create a couple of memory DCs
4. Select the images into their own DCs
5. BitBlt from the DC holding the HBITMAP to the one containing the DIBSection
6. Save the DIBSection to disk (you can use the supplied function)
7. Deselect the images from their DCs
8. DeleteObject both images (HBITMAP & DIBSection)
BOOL SaveBitmapFile(HDC p_hDC, LPCTSTR p_pchFileName)
{
HBITMAP hBmp = (HBITMAP)GetCurrentObject( p_hDC, OBJ_BITMAP );
BITMAPINFO stBmpInfo;
stBmpInfo.bmiHeader.biSize = sizeof( stBmpInfo.bmiHeader );
stBmpInfo.bmiHeader.biBitCount = 0;
GetDIBits( p_hDC, hBmp, 0, 0, NULL, &stBmpInfo, DIB_RGB_COLORS );
ULONG iBmpInfoSize;
switch( stBmpInfo.bmiHeader.biBitCount )
{
case 24:
iBmpInfoSize = sizeof(BITMAPINFOHEADER);
break;
case 16:
case 32:
iBmpInfoSize = sizeof(BITMAPINFOHEADER)+sizeof(DWORD)*3;
break;
default:
iBmpInfoSize = sizeof(BITMAPINFOHEADER) +
sizeof(RGBQUAD) * ( 1 << stBmpInfo.bmiHeader.biBitCount );
break;
}
PBITMAPINFO pstBmpInfo;
if( iBmpInfoSize != sizeof(BITMAPINFOHEADER) )
{
pstBmpInfo = (PBITMAPINFO)GlobalAlloc( GMEM_FIXED | GMEM_ZEROINIT, iBmpInfoSize );
PBYTE pbtBmpInfoDest = (PBYTE)pstBmpInfo;
PBYTE pbtBmpInfoSrc = (PBYTE)&stBmpInfo;
ULONG iSizeTmp = sizeof( BITMAPINFOHEADER );
while( iSizeTmp-- )
{
*( ( pbtBmpInfoDest )++ ) = *( ( pbtBmpInfoSrc )++ );
}
}
HANDLE hFile = CreateFile( p_pchFileName, GENERIC_WRITE, 0,
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_ARCHIVE,
NULL );
BITMAPFILEHEADER stBmpFileHder;
stBmpFileHder.bfType = 0x4D42;
stBmpFileHder.bfSize = sizeof(BITMAPFILEHEADER)
+ sizeof(BITMAPINFOHEADER)
+ iBmpInfoSize
+ pstBmpInfo->bmiHeader.biSizeImage;
stBmpFileHder.bfReserved1 = 0;
stBmpFileHder.bfReserved2 = 0;
stBmpFileHder.bfOffBits = sizeof(BITMAPFILEHEADER) + iBmpInfoSize;
DWORD dRet;
WriteFile( hFile, (LPCVOID)&stBmpFileHder , sizeof(BITMAPFILEHEADER), &dRet, NULL );
PBYTE pBits = (PBYTE)GlobalAlloc( GMEM_FIXED | GMEM_ZEROINIT, stBmpInfo.bmiHeader.biSizeImage );
HBITMAP hBmpOld;
HBITMAP hTmpBmp = CreateCompatibleBitmap( p_hDC,
pstBmpInfo->bmiHeader.biWidth,
pstBmpInfo->bmiHeader.biHeight );
hBmpOld = (HBITMAP)SelectObject( p_hDC, hTmpBmp );
GetDIBits( p_hDC, hBmp, 0, pstBmpInfo->bmiHeader.biHeight,
(LPSTR)pBits, pstBmpInfo, DIB_RGB_COLORS );
WriteFile( hFile, (LPCVOID)pstBmpInfo, iBmpInfoSize, &dRet, NULL );
WriteFile( hFile, (LPCVOID)pBits, pstBmpInfo->bmiHeader.biSizeImage, &dRet, NULL );
SelectObject( p_hDC, hBmpOld );
DeleteObject( hTmpBmp );
CloseHandle( hFile );
GlobalFree( pstBmpInfo );
GlobalFree( pBits );
return TRUE;
}
|
|
|
|
|
Thanks for your reply.
Do you think writing the DIB to a xml file and reading back and displaying it will actually display it?
|
|
|
|
|
Do you think writing the DIB to a xml file and reading back and displaying it will actually display it?
Well that is the tricky part - it is important to choose what kind of DIB you want, so you can read it latter on Mac:
- choose how many colors
- by default DIB is bottom-up. If Mac can't read it put negative height in DIB
- if Mac can read .bmp, consider writing the file in .bmp rather .xml (this will greatly reduce file size and writing routines to read .xml)
Good luck.
|
|
|
|
|
My pleasure.
Sure, writing a bitmap to an XML file will work, it'd just be more work than saving the DIBSection to a BMP file (the code supplied will create a BMP file)
You'll be able to open the created file with photoshop or any other image program that supports BMP. I wrote the code from scratch, the BMP format is really fairly simple. Just use your preferred method, either would work.
|
|
|
|
|
I cant use a bmp file, because bmp is not the only info I need to send to the mac. I want to club whole info into a single xml file, transfer it, and then disintegrate it on the mac.
|
|
|
|
|
What image format does the bitmap need to be in for the Mac to read it?
It seems to me there's three steps here:
1) Write the DDB to an image stream in some Mac-recognizable format
2) Send the stream bytes via XML
3) Extract the byte stream into an image
Which part is giving you trouble?
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
The first part.
1) Write the DDB to an image stream in some Mac-recognizable format
I thought of writing the BITMAP structure field by field to the xml, including the color bits(pBmBits field). I convert this bmbits field to string before writing. Somehow the size of the xml file after writing the image data increases to 6MB, while the image is only 66KB.
Is it OK to convert it to string before writing?
How can I convert it to a stream?
|
|
|
|
|
ThisIsMeRon wrote: Write the DDB to an image stream in some Mac-recognizable format
What would that format be?
Do you need to break apart the bitmap and just send basic info like
height, width, bits-per-pixel, and the pixel bits?
Or can you send a stream of a "universal" image format like TIFF, JPEG, etc.
(the Mac probably reads BMPs fine as well I would think).
66K to 6MB .... definitely something wrong there
Even if you send a base64 representation of the binary data, you should
only see an increase of 33%.
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Use the CopyImage function.
HBITMAP DIBBitmap = CopyImage(DDBBitmap, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION)
You may be right
I may be crazy
-- Billy Joel --
Within you lies the power for good - Use it!
|
|
|
|
|
Hi,
I will like to know which C++ compiler implements the most complete C++ and STL Specification/Standards as of today?
Also what is the state of latest C++0.x specification (as of today) and conformance of the current compilers?
Thanks and Regards
|
|
|
|
|
Hi all,
I have to rename the Ok and cancel of a message Box
AfxMessageBox("Message ", "Name", MB_OK | MB_SYSTEMMODAL);
i want to change the name of Ok--->update
Cancel--->dont Update
can you help me..
vikas da
|
|
|
|
|
|
you can create your own dialog and make it look similar to a message box. A simpler technique...
You need to google first, if you have "It's urgent please" mentioned in your question.
_AnShUmAn_
|
|
|
|
|
When running on Vista and later, you can use a task dialog for that. Otherwise, for earlier OSes, you'll need a custom-written dialog as the other replies have suggested.
|
|
|
|
|
Hi,
I have creted a MFC SDI project in VC 2008 and compiled in Vista OS. Now when i copied the project into XP OS system and opened. I can open all views(class view, solution explorer...) but the resource view...
it is showing a MessageBox stating
A resource in file uses an unknown language:English(U.S.)(unknown sub-lang:0x10).
Unable to open this file.
Did anybody come across this problem...
Thank you.
Tritva
|
|
|
|
|
Open your resource script file, and delete this part from it:
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) (unknown sub-lang: 0x10) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENN)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, 0x10
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// RT_MANIFEST
//
2 RT_MANIFEST "XenonOcx.manifest"
#endif // English (U.S.) (unknown sub-lang: 0x10) resources
/////////////////////////////////////////////////////////////////////////////
It solves your problem.
|
|
|
|
|
I dont seem to be displaying any text
would anyone know what I am doing wrong
Stor_edit = GetDlgItem(hwndDlg,IDC_EDIT3);
<br />
SendMessage(Stor_edit,EM_POSFROMCHAR,(WPARAM) 1, NULL);
<br />
x = LOWORD(myresult);<br />
<br />
y = HIWORD(myresult);<br />
<br />
mydc = GetDC(Stor_edit);<br />
<br />
SetTextColor(mydc, RGB(255,0,0));<br />
<br />
SetBkColor(mydc, RGB(255,255,0));<br />
<br />
SelectObject(mydc,CreateSolidBrush(RGB(255,255,206,0)));<br />
<br />
GetTextMetrics(mydc,&mytext);<br />
<br />
x = x * mytext.tmOverhang;<br />
<br />
y = y * mytext.tmHeight;<br />
<br />
TextOut(mydc,x,y,"Test String",10);<br />
<br />
ReleaseDC(Stor_edit,mydc);<br />
<br />
return TRUE;
|
|
|
|
|
Why are you using TextOut?
Use SetWindowText.
I hope it helps.
Regards,
Sandip.
|
|
|
|
|
isn't SetWindowText For the title Bar ????
|
|
|
|
|
If the window does not have a title bar it will set it to its body...
|
|
|
|
|
I am sorry I really down understand ??? I think I have title bar set in in resource of the DialogBox templete
of which this edit control is a part of
|
|
|
|
|
Edit controls render the text themselves.
You don't draw the text on top of an edit control.
"The SetWindowText function changes the text of the specified
window's title bar (if it has one). If the specified window is
a control, the text of the control is changed."
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Hi,
My plan was to make Certin parts of the Text Highlighted/Colored
that why I went into GDI/HDC mode
Can you do Device Context e.g. GDI stuff with a Multi Line edit control ?????
or am I totally way off base
BTW ipc communication via named pipes I finally got that to work
Can I buy you dinner sometimes
Thankx for your help
|
|
|
|
|
ForNow wrote: Can you do Device Context e.g. GDI stuff with a Multi Line edit control ?????
You can, but you'll be fighting the control's drawing implementation.
ForNow wrote: My plan was to make Certin parts of the Text Highlighted/Colored
Using a Rich Edit control would make that much simpler!
ForNow wrote: BTW ipc communication via named pipes I finally got that to work
Cool!
ForNow wrote: Can I buy you dinner sometimes
Of course! I never turn down a free meal
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
ok I see it much simpler the n WM_PAINT or WM_CTLCOLOREDIT
one last question I implemented multiline edit control via DialogTemplete
can I still use that interface for Rich Edit ???
BTW as far free meal I am on the easT cost specfically White Plains NY
|
|
|
|