|
Glad you found the solution. Come back and visit us again.
|
|
|
|
|
I need to convert raw bitmap data into a CBitmap that can be added to a CImageList.
The raw data does not come from a file, but rather from a network transaction. As such, I cannot use LoadImage to create an HBITMAP that can be attached to CBitmap - nor do I want to save the data to file in order to do so.
Looking for any code snipet or at least a brief explanation on the procedure.
Many thanks in advance.
|
|
|
|
|
One way is to use CreateDIBSection[^]
Basic steps are:
1) Initialize a BITMAPINFO struct that describes the dimensions and format of the bitmap data
2) Call CreateDIBSection(), using a screenDC or a DC with the appropriate palette selected into
it if your pixel format is <16 bits-per-pixel.
3) The pointer returned by CreateDIBSection() (in your supplied ppvBits param) is where you copy
your pixel data to. Note that each row is aligned to a DWORD (4 bytes) so if your source data
is not DWORD aligned then do the copy appropriately to align the rows properly.
4) The HBITMAP returned by CreateDIBSection() can be used like any bitmap - selected into a DC,
added to an image list, etc.
If you are doing many operations on the same image dimensions/format, you can reuse the DIBSection
instead of creating a new one each time.
Mark
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder
|
|
|
|
|
Thanks for your reply, Mark.
However, I need a little more info (I apologize for not be more specific in my first message).
The data I'm receiving over the network is the actual contents of a bitmap file, so I'm assuming that the BITMAPFILEHEADER, BITMAPINFO, BITMAPINFOHEADER structures, as well as the bits and palette data, are already set up. I know that this received data is valid because I've been able to successfully save it to disk and load it up in an image editor, like Paint.
I've been experimenting with the following code (minus error handling et al), but so far all I get is a black box whenever I draw the bitmap.
BOOL LoadBitmap(PBYTE pbData, // pointer to data received over network
CBitmap &bmp) // destination CBitmap object.
{
PBITMAPFILEHEADER pBmpFileHdr = (PBITMAPFILEHEADER)pbData;
PBITMAPINFO pBmpInfo = (PBITMAPINFO)(pbData + sizeof(BITMAPFILEHEADER));
PBITMAPINFOHEADER pBmpInfoHdr = &pBmpInfo->bmiHeader;
PVOID pvBits = pbData + pBmpFileHdr->bfOffBits;
HDC hDC = CreateCompatibleDC(NULL);
HBITMAP hBitmap = CreateDIBitmap(hDC, pBmpInfoHdr, CBM_INIT, pvBits, pBmpInfo, DIB_RGB_COLORS);
DeleteDC(hDC);
return bmp.Attach(hBitmap);
}
Note that everything 'seems' to work (ie. no errors returned and structures contain valid data), but it appears that 'bmp' is not initialized properly.
|
|
|
|
|
fixitnow wrote: but it appears that 'bmp' is not initialized properly.
How so?
Mark
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder
|
|
|
|
|
Sorry for delay - had other bugs to fix.
It appears that I'm missing color information: when I draw the bitmap it's black and white, and in some cases it's all black.
The confusing thing for me is that it draws fine if I save the data to disk and then load it with LoadImage.
|
|
|
|
|
Since you are using CreateDIBitmap(), the DC you use is going to determine the format of the
destination bitmap.
By default a DC has a monochrome bitmap selected into it, so that's the format you're going to
get.
You have (at least) two alternatives to fix this:
1) Create a DDB bitmap (HBITMAP) of the desired destination bitmap format and select it into the
DC before calling CreateDIBitmap().
2) Use CreatDIBSection section to create the destination bitmap and copy the source pixel bits
to the DIBSection's DIB bits.
Mark
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder
|
|
|
|
|
Hi I m using bloodshed DevC++ 4.9.9.2 for win32 programming I am unable to use the code completion feature after enabling "class browser", "code completion" and "code completion cache", when i hit a dot after any structure variable (say, WNDCLASSEX wincl), My mouse cursor just blink for a second a waiting busy cursor appears and goes off, even i tried hitting Ctrl+Spacebar same thing appears mouse cursor blinks and then nothing happens, Plz help.
Thanks in Advance,
Sumit
|
|
|
|
|
SumitMandal wrote: I m using bloodshed DevC++ 4.9.9.2
There are probably not too many people here on CP using that development environment. You would have better luck getting an answer to find a DevC++ forum.
|
|
|
|
|
Hi
In that article (http://www.codeproject.com/dialog/messagehandling.asp) it writes:
In fact, all the standard controls are simply windows with Message handlers. Take a Button for example. When it gets a WM_PAINT message it will draw the button. When you Left-click the button, it gets a WM_LBUTTONDOWN message, and it draws the pressed-button. When you let go of the mouse button it receives a WM_LBUTTONUP message, and respectively draws the button.
When user click button windows put message in programs message queue.
Does windows also put WM_Paint message to controls queue?
I dont understand here. There are 2 messages, one of the buttondown, the other paint. buttondown sends to my program but how does window achieve repainting?
Is there one more buttondown message handler in button control? Does windows put buttondown both my program and control?
Can you please explain here.
Thanks
|
|
|
|
|
Indeed, if windows needs to repaint an object the WM_PAINT is sent to the control.
A WM_LBUTTONDOWN is for a click that a control receives... (=> user clicks on control, e.g)
I guess that WM_PAINT is sent, too, because the button might get a little indentet, so it needs to be repaint
|
|
|
|
|
This is correct for some standard window classes. But if i am creating a owner draw control like that, it depends upon me , what to do , whether paint or not. So Normally we need to paint on mouse messages to give a feeling to the user...
If u can Dream... U can do it
|
|
|
|
|
Windows simply puts the WM_LBUTTONDOWN in the queue, it is up to the window to decide how it responds, different windows will respond differently.
A button probably changes its internal state to 'pressed' and calls Invalidate() which is its way of asking Windows for a WM_PAINT message. It will also fire off a notification message to its parent to let it know that it has been pressed. In response to the WM_PAINT message it will draw its 'pressed' state.
A Static text control may ignore mouse messages. You could modify this behaviour by adding a WM_LBUTTONDOWN handler, you may decide to change what is displayed so you could modify some saved data and call Invalidate(), and when the WM_PAINT message arrives draw the new data. Doing this you could make it behave like a button for example (you would also have to handle the WM_LBUTTONUP message).
Peter
"Until the invention of the computer, the machine gun was the device that enabled humans to make the most mistakes in the smallest amount of time."
|
|
|
|
|
Hi All
I have a three radio controls on my dialog within a group box,
at certain points i wish to hide or show these
normally if i want to show/hide something i would just do my_var.ShowWindow(SW_SHOW/SW_HIDE);
as i have three radio controls within a group i can only add a control variable to the first item in the group
so i can hide/show this item quite easily, but the other two i cant add control variable
so i cant see a way to hide or show these other two raido controls
can anyone help. hope that all makes sense
Simon
|
|
|
|
|
GetDlgItem(IDC_RADIO2)->ShowWindow(false);
Shog on learning VB6: Ah, that would have been VB6. Kicked my ass anyway. So easy to learn, just like falling down a flight of stairs...
|
|
|
|
|
|
Actually, ShowWindow (SW_HIDE) .
/ravi
|
|
|
|
|
si_69 wrote: as i have three radio controls within a group i can only add a control variable to the first item in the group
This is a common misconception. Each radio button can have it's own control variable.
si_69 wrote: can anyone help. hope that all makes sense
I prefer to use this[^] class.
"A good athlete is the result of a good and worthy opponent." - David Crow
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
Hi,
I am new to windows programming. In my code I would require to change the slider bar position, which I have accomplished by sending message.
::SendMessage( aControlHWnd, TBM_SETPOS, (WPARAM) (BOOL) TRUE, (LPARAM)(LONG) aPosition );
The problem is with the updation of the window according to the new sliderbar position, I mean, when I change the position of the sliderbar it is changed visually, but the corresponding values in other objects (like textbox showing the value related to this sliderbar) are not updated.
To accomplish this I tried
::NotifyWinEvent( EVENT_OBJECT_VALUECHANGE, theDialogHWnd, OBJID_HSCROLL, CHILDID_SELF );
where theDialogHWnd is the handle for the dialog window containing the sliderbar and the textbox, but it didn't work. I am not sure if the parameters I am using are correct, or the event I am trying to notify, or may be my approach to the problem itself is wrong. I do understand that this can be easily accomplished by sending a keyboard or mouse event, but I am tryin not to use it.
Any help would be greatly appriciated.
Thanks.
|
|
|
|
|
I'm not too sure, but try to set
UpdateData(TRUE);
on the control
|
|
|
|
|
Instead of NotifyWinEvent(), you could just add a function to your dialog window class
(or wherever appropriate) which updates all the related controls based on the trackbar's position.
Call this function whenever you set the position programmatically and also call it when you're
notified that the user has changed the position.
Mark
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder
|
|
|
|
|
i want to check greater than 255 value in ipaddress field but when i enter value greater than 255 it automatically change to 255 at that time i cant get what i typed.so i cant check greater than 255 value.how can i do that
|
|
|
|
|
Then It wouldn't be an IPaddress
What's your purpose of doing that?
--
=====
Arman
|
|
|
|
|
when the user type greater then 255 i want to post a error message.
In windows Local area Connection wizard display this kind of message.i want to do that like this.
|
|
|
|
|
Hi,
The one way could be by customizing the CEdit control using mask. You create ur own IPAddress control class, in which u can handle all validations as per your requirement.
Manoj
Never Give up
|
|
|
|