|
I have a dialog which I have set as a tool window so it is always on top. Within this window I want to dynamically load buttons each with a different bitmap on. Someone has suggested that I use CreateWindow and pass a flag to say it will be of style BUTTON so I use the following code
CreateWindow("BUTTON",
"sample",
BS_BITMAP,
5,
5,
100,
100,
m_hWnd,
NULL,
NULL,
NULL);
I'm assuming that m_hWnd member variable should be a handle to the dialog box when it is shown, but when tested comes through as NULL and nothing is shown in the dialog box. What am I doing wrong?
Thanks for any help in advance
Nick
|
|
|
|
|
you must call ShowWindow() function after CreateWindow().
F.Julien
|
|
|
|
|
thanks, but do I put those in the constructor of the containing dialog because obviously the buttons will be part of this. When doing this I get an assertion error, I think its talking about a NULL handle to this dialog which I thought would be a problem.
Nick
|
|
|
|
|
Don't call CreateWindow on the buttons in the dialog's constructor - the dialog window won't be created yet so you can't use it as a parent window. Call CreateWindow in CYourDialog::OnCreate() (if you use MFC) or in response to the WM_CREATE msg (if non-MFC) instead. Since it's a dialog you can also put the calls in OnInitDialog/WM_INITDIALOG instead.
Cheers
Steen.
"To claim that computer games influence children is rediculous. If Pacman had influenced children born in the 80'ies we would see a lot of youngsters running around in dark rooms eating pills while listening to monotonous music"
|
|
|
|
|
thanks a lot, that worked fine
Nick
|
|
|
|
|
You need to call to ShowWindow Function, but you are missing same values in the style parameter like WS_CHILD | WS_VISIBLE whit this last parameter don't you need to call to ShowWindow function.
Cheers
Carlos Antollini.
|
|
|
|
|
Button style should contain WS_CHILD and WS_VISIBLE:
CreateWindow("BUTTON",
"sample",
WS_CHILD | WS_VISIBLE | BS_BITMAP,
5,
5,
100,
100,
m_hWnd,
NULL,
NULL,
NULL);
You should also pass a child window id after m_hWnd.
Tomasz Sowinski -- http://www.shooltz.com
|
|
|
|
|
How do I get this child window ID?
So far I have the following code:
CreateWindow( "BUTTON",
"sample",
WS_CHILD | WS_VISIBLE | BS_BITMAP,
5,
5,
20,
20,
m_hWnd,
/*the child window ID will go here*/,
NULL,
NULL);
HBITMAP hBmp = (HBITMAP)::LoadImage(AfxGetInstanceHandle(), "c:\\1.bmp", IMAGE_BITMAP, 16, 16, LR_LOADFROMFILE);
::SendMessage((HWND)hButton, BM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)hBmp);
Thanks for the help so far
Nick
|
|
|
|
|
How do I get this child window ID?
You don't get this ID, you have to come up with one yourself. This ID is passed back (as LOWORD(wParam) in WM_COMMAND) to the parent window when somebody clicks the button - you'll need to recognize which button was pressed, right?
You can use any scheme to create IDs to your buttons.
Tomasz Sowinski -- http://www.shooltz.com
|
|
|
|
|
So for example, I could set it as 966 by doing
int hButton = 966;
and including hButton under/after the m_hWnd parameter, because I already tried that. If that is correct, there is something else wrong, probably in the loading of the bitmap because when the program is run it show's no bitmap on the button.
Nick
|
|
|
|
|
hButton is a window handle, not a child ID. Store value returned from CreateWindow in hButton. Use some predefined constant and pass it as child ID to CreateWindow. Use the same constant when handling WM_COMMAND - you'll be able to respond differently to different buttons being pressed.
Tomasz Sowinski -- http://www.shooltz.com
|
|
|
|
|
Sorted, thank you very much, much appreciated.
Nick
|
|
|
|
|
This is exactly what I'm doing, but in WM_COMMAND all WPARAM wp ever is is 0x0000FFFF
any ideas why?
I set it to
#define BTN_ONE 301
Thanks
|
|
|
|
|
I would like to create a function which could return 2 COleDateTime objects simultaneously, so i think that i could use a pointer of COleDateTime. But, as i'm a beginner in C++, i would like to know if someone could show me how we could do the allocation of this pointer, his deletion, and how i could return the dates, as i want the function return dates?
thanks in advance
gerald
|
|
|
|
|
You create the Objects dynamically
COleDateTime* pDate1 = new COleDateTime();
COleDateTime* pDate2 = new COleDateTime();
These objects are not gonna be destroyed if you leave the scope of this function !!
You can acess all the member - Fun´s and Var´s by using the -> operator:
pDate1->GetStatus();
You wanna get rid of them:
delete pDate1;
delete pDate2;
if this helps you... fine.. if not.. you can ask me..
Bernhard
- I heard if you play the Windows CD backwards, you get a satanic message.
- That's nothing, if you play it forward, it installs Windows!
|
|
|
|
|
ok with your answer, but how could i return the values of 2 dates with 1 function?
|
|
|
|
|
May I suggest you use a struct holding the two dates just like this:
typedef struct{
COleDateTime firstDateTime;
COleDateTime secondDateTime;
}PairCOleDateTime; and have your function return a PairCOleDateTime instead of a pointer. This way you get rid of all sorts of allocation/deallocation problems, and the extra cost of returning this struct by value should be negligible for most purposes.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
and if i define this struct, how could i use it in a function which modify or use the dates?
|
|
|
|
|
void GetTime(COleDateTime* pDate1, COleDateTime* pDate2)
{
pDate1 = new COleDateTime();
pDate2 = new COleDateTime();
//Fill the Objects with Data or do whatever you want to do with them
}
//Your Main Function
void WaWa()
{
COleDateTime* pDate1 = 0;
ColeDateTime* pDate2 = 0;
GetTime (pDate1, pDate2);
//Do whatever you want to do with em..
pDate1->GetTime();
pDate2->GetTime();
//if you´ve finished.. get rid of em..
delete pDate1;
delete pDate2;
}
Another version would be to allocate them in the main function (WaWa).. but that´s just an answer of how you would like to do this..
i hope this helped you..
Bernhard
- I heard if you play the Windows CD backwards, you get a satanic message.
- That's nothing, if you play it forward, it installs Windows
|
|
|
|
|
my function take 2 coledatetime parameters AND modify them and returnthe modification on this 2 dates, but i don't know how to do that!
|
|
|
|
|
I think using references would be easiest way:
void myFunc(COleDateTime & d1, COleDateTime & d2)
{
}
COleDateTime x, y;
myFunc(x, y);
Tomasz Sowinski -- http://www.shooltz.com
|
|
|
|
|
If you would like to allocate an array of COleDateTime objects dynamically here's how you do it:
COleDateTime* CMyClass::AllocTwoDates()
{
COleDateTime* pDate = new COleDateTime[2];
return pDate;
}
When you're through using the allocated objects delete them:
void CMyClass::SomeFunction()
{
COleDateTime* pDates = AllocTwoDates()
delete[] pDates;
}
Remember to use the delete[] operator instead of the delete operator, otherwise the constructors of the COleDateTime objects will not get called.
Cheers
Steen.
"To claim that computer games influence children is rediculous. If Pacman had influenced children born in the 80'ies we would see a lot of youngsters running around in dark rooms eating pills while listening to monotonous music"
|
|
|
|
|
So, if i want to modify the dates i have allocated first with AllocTwoDates(), for example in SomeFunction(), we could know the modifications after the use of this function even if we delete it?
|
|
|
|
|
This reply got longer than I intended, sorry about that. Anyway, here goes:
I'm not too sure what you mean. But if you delete the array of dates then all the information contained in the date objects are gone.
void CMyClass::SomeFunction()
{
COleDateTime* pDates = AllocTwoDates();
pDates[0] = COleDateTime::GetCurrentTime();
pDates[1].SetDate(pDates[0].GetYear()+1 ,pDates[0].GetMonth() ,pDates[0].GetDay());
delete[] pDates;
CString cs = pDates[1].Format(%d %b %Y);
If you want to keep the date objects after SomeFuntion() returns you should make pDates a member variable instead, do the allocation in the constructor (if possible) and the deletion in the destructor. If the number of objects in the date array changes in CMyClass' lifetime you should at least delete the pointer in the destructor:
class CMyClass
{
public:
CMyClass();
~CMyClass();
void SomeFunction();
void UseTheDates();
protected:
void AllocTwoDates();
void DeleteDates();
const COleDateTime* GetDates();
private:
COleDateTime* m_pDates;
};
CMyClass::CMyClass()
{
m_pDates = NULL;
}
CMyClass::~CMyClass()
{
DeleteDates();
}
void CMyClass::SomeFunction()
{
AllocTwoDates();
}
void CMyClass::UseTheDates()
{
if (GetDates() != NULL) {
}
}
void CMyClass::AllocTwoDates()
{
DeleteDates();
m_pDates = new COleDateTime[2];
}
void CMyClass::DeleteDates()
{
if (m_pDates != NULL) {
delete[] m_pDates;
m_pDates = NULL;
}
}
Note that I've changed AllocTwoDates so it works directly on the member variable instead of returning the pointer. There is no need to return a pointer to a private member - it's accessible via the member variable from any member function (including members of derived classes) and shouldn't be accessibel from outside CMyClass. This way you're sure that only methods in CMyClass can modify m_pDates. No derived classes or outside classes can reach m_pDates directly, but has to get the pointer through GetDates(). This method returns a pointer to const COleDateTime objects and this pointer cannot be an argument for delete[]. In effect, only DeleteDates() can do the deletion, and only AllocTwoDates() can do the allocation. Voila, no memory leaks!
Anyway, you should store the size of your m_pDates array somewhere (e.g. in a member variable, m_iSizeDates). This way you can avoid accessing illegal memory (e.g. m_pDates[2] in the example above).
Finally, the STL vector class or the MFC CArray template class may prove more suitable for you - they take care of allocation/reallocation and deletion, and you can pass them instead of a COleDateTime* to functions.
Cheers
Steen.
"To claim that computer games influence children is rediculous. If Pacman had influenced children born in the 80'ies we would see a lot of youngsters running around in dark rooms eating pills while listening to monotonous music"
|
|
|
|
|
perhaps, the 2 last questions.
1. i don't really understand what represent the function GetDates(), and if it's necessary to use it.
2. You use firstly a function SomeDates, where you do the allocation, and in a second time, you create UseTheDates(), but i could use AllocTwoDates in this last function?
thanks for your great help
gerald
|
|
|
|
|