|
Thanx -- I thought it might work that way -- still seeking a more elegant solution though
Trying not to create to many layers of classes between parent and the meat operations of the derived listbox
MFC does it Re Combobox (Listcontrol+edit) and they probably did it that way
|
|
|
|
|
A bit stuck on placing frame on dialog
Added Cframewnd LBA Via class wizard to project
Edited in the following
LBA.h
pragma once
#include "listboxadv.h"
#include "afxwin.h"
#include "MediaPlayer.h"
class LBA : public CFrameWnd
{
DECLARE_DYNCREATE(LBA)
public:
LBA();
virtual ~LBA();
protected:
DECLARE_MESSAGE_MAP()
public:
CToolBar m_toolbar;
ListBoxAdv m_list;
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnSize(UINT nType, int cx, int cy);
CComboBox m_combobox;
CEdit m_searchfor;
CEdit m_sortstring;
};
LBA.cpp
/ LBA.cpp : implementation file
#include "stdafx.h"
#include "MediaPlayer.h"
#include "LBA.h"
IMPLEMENT_DYNCREATE(LBA, CFrameWnd)
LBA::LBA()
{
}
LBA::~LBA()
{
if(IsWindow(m_toolbar.GetSafeHwnd()))m_toolbar.DestroyWindow();
if(IsWindow(m_list.GetSafeHwnd()))m_list.DestroyWindow();
if(IsWindow(m_searchfor.GetSafeHwnd()))m_searchfor.DestroyWindow();
if(IsWindow(m_combobox.GetSafeHwnd()))m_combobox.DestroyWindow();
if(IsWindow(m_sortstring.GetSafeHwnd()))m_sortstring.DestroyWindow();
}
BEGIN_MESSAGE_MAP(LBA, CFrameWnd)
ON_WM_CREATE()
ON_WM_SIZE()
END_MESSAGE_MAP()
int LBA::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
CRect rec;
int i;
.... all the toolbar code
Then used dialog editor -- added Picturebox as a placeholder,and control variable m_ctrllist
Edited dialog header so
LBA m_ctrllist
And ran the code
resized m_ctrllist in dialog::OnInitDialog --LBA::OnSize was called worked fine
BUT -- Had a break in LBA::OnCreate it was never tripped
and dialog shows a picture box (as you would expect since OnCreate was never invoked)
So tried deleting the picturebox and added to Dialog::OnCreate() the following
CRect rec;
m_ctrllist.Create(_T("FrameWnd"),NULL,WS_VISIBLE|WS_CHILD,rec,this,NULL,0);
Heap errors up the yazoo
I'm Missing something very basic
|
|
|
|
|
OnCreate() is not called for controls created by dialog templates. So overriding LBA::OnCreate() does not help here.
|
|
|
|
|
Yes I thought it was a hail mary.
The first answer in this tree was Just "place on dialog or view surface"
and I'm betting adding m_ctrllist.OnCreate(... to OnInitialDialog isn't the right way either
No it isn't --So I'm stumped
modified 8-Feb-12 8:57am.
|
|
|
|
|
Fallen123 wrote: The first answer in this tree was Just "place on dialog or view surface"
That should be best way.
May be this notes are useful:
You added a picture box as placeholder. I would use a simple control (e.g. static text) as placeholder. This should have the same size as your overlayed bar and be hidden by default. The only reason to add a member var for this control would be to get its size. Don't touch this var/control elsewhere (especially, don't try to delete it).
An overlayed control should be created on the heap from within OnInitDialog() (you tried to use a member var):
CMyBar* m_pBar;
m_pBar = new CMyBar;
m_pBar->Create(this, WS_CHILD, ...);
You may also check if you can implement your bar using a CDialogBar derived class. This is perfect for such tasks and provides auto delete.
|
|
|
|
|
Nope
m_ptrlist=new LBA;
rec.left=7;rec.right=1607;rec.top=70;rec.bottom=752;
if(!m_ptrlist->Create(_T("LBA"),NULL,WS_VISIBLE|WS_CHILD,rec,this))
{
MessageBox(_T("Failed"));
long k=GetLastError();
k=k;
failed kicks with no error return
changed windowclassname to null -- It created sucessfully
But throwing exceptions -- Will have to wade through
modified 8-Feb-12 10:15am.
|
|
|
|
|
::GetLastError() is only set by API functions, not by MFC functions.
You may set a breakpoint and trace into the Create() function to check where it fails.
You are passing 'LBA' as class name. I'm not really sure, but I think the name must be registered for frame windows.
Think about the CDialogBar option. It uses a normal dialog template. However, if you want toolbar like symbol buttons, they must be added to the template.
|
|
|
|
|
Yes I figured it out --Got the view and it has the toolbar and listbox --
Now its just fixing all the bugs
Thanx for the help
|
|
|
|
|
Please try it :
1. ~LBA() does not need to destroy any child
2. ~CYourDialog() does not need to destroy any child
3. Please place a static in the dialog editor with the IDC_LISTFRAME (not IDC_STATIC).
4. Then - in OnInitDialog() -
{
..
CWnd* pcWnd(GetDlgItem(IDC_LISTFRAME));
if (pcWnd->GetSafeHwnd()) {
CRect crFrame;
pcWnd->GetWindowRect(crFrame);
pcWnd->DestroyWindow();
ScreenToClient(crFrame);
m_cListFrame.Create(LBA::staticClassStringGottenByAfxRegisterClass,
NULL,
WS_CHILD|WS_WISIBLE|WS_BORDER,
crFrame,
this);
}
..
}
They sought it with thimbles, they sought it with care;
They pursued it with forks and hope;
They threatened its life with a railway-share;
They charmed it with smiles and soap.
|
|
|
|
|
Okay I created this in LBA (basically copied meat from MS
CString LBA::RegisterLbaAsClass(void)
{
WNDCLASS wndcls;
CString hold=_T("ListBoxAdvanced");
memset(&wndcls, 0, sizeof(WNDCLASS));
wndcls.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
wndcls.lpfnWndProc = ::DefWindowProc;
wndcls.hInstance = AfxGetInstanceHandle();
wndcls.hIcon = NULL;
wndcls.hCursor = NULL;
wndcls.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wndcls.lpszMenuName = NULL;
wndcls.lpszClassName = _T("ListBoxAdvanced");
if(!AfxRegisterClass(&wndcls))
{
TRACE("LBA Class Registration Failed\n");
}
return hold;
}
And This in OnInitialDialog
CWnd* pcWnd=GetDlgItem(IDC_MovieCtrl);
if (pcWnd->GetSafeHwnd())
{
rec.left=7;rec.right=1607;rec.top=70;rec.bottom=802;
pcWnd->DestroyWindow();
}
CString hold=m_movielist.RegisterLbaAsClass();
if(!m_movielist.Create(hold,NULL,WS_CHILD|WS_VISIBLE|WS_BORDER,rec,this))
{
MessageBox(_T("Failed"));
long k=GetLastError();
k=k;
}
it throws exception during movielist.Create ...
Unhandled exception at 0x77544621 in MediaPlayer.exe: 0xC015000F: The activation context being deactivated is not the most recently activated one.
Truly confused -Not at all sure what I'm doing
never had to register my derived class before -They were all derived from std controls easy peasy
Figured it out -- turned on win32 exceptions -- error showed right up
Last thing to tangle with -- heap corruption on exit -I Hate these they could be anywhere
Well thanx for your help
modified 10-Feb-12 1:20am.
|
|
|
|
|
Please try it at the end of your OnInitDialog() (I have tried it as well) :
m_cFrame.Create(AfxRegisterWndClass(CS_DBLCLKS),
NULL,
WS_CHILD|WS_VISIBLE,
CRect(10, 10, 100, 100) ,
this);
Please overwrite also the following reaction for your frame:
void CYourFrame::PostNcDestroy()
{
}
They sought it with thimbles, they sought it with care;
They pursued it with forks and hope;
They threatened its life with a railway-share;
They charmed it with smiles and soap.
|
|
|
|
|
Yes - Overriding PostNcDestroy did it . In my traces exception also ended up at that point.
Just wasn't comfortable stomping on it like that. Still Kinda curious what I'm doing wrong though -- can't find anything.
I've tried exiting the moment I enter OnInitialDialog -- still throws the @#$%! Heap exception!
So I'm guessing the heap is still corrupted on exit -HoHum
Putting the Create at the end of the OnInitialDialog doesn't matter here - I ended Up creating one function In LBA that registered the LBA class(First time through)then created the LBA frame (which triggered the LBA::OnCreate for the toolbar and Listbox)...
So Making all the creation code in the LBA class -- cuts down on coding to use the class
And used that function in OnInitialDialog (almost at the start)
LBA m_movieframe in Mydialog.h
m_movieframe.UpgradeLB_LBA(CWnd *ptr to static placeholder,&m_movieframe,CWnd *ptr dialog)
passed ptr parent as at the called point as LBA *Cwnd didn't exist (so hard to get to the parent)
This function grabs the static's rectangle ,destroys the static ,reassigns the CtrlId to the frames listbox (Important for trapping LBSelChanged messages ... via the dialogs messagemap.) gotta have a hard CtrlId target
I'm using 6 of this LBA Class in my Dialog
Now --Just to get the trap the messages toolbar, listbox messages to handlers (Duck Soup)
|
|
|
|
|
You cannot add a toolbar to a child window, only to a frame, so you should add the menu to your dialog resource.
Unrequited desire is character building. OriginalGriff
I'm sitting here giving you a standing ovation - Len Goodman
|
|
|
|
|
Yes - I gathered that I could only add it to the dialog. Done that
But then I'd like to redirect Messages from the parent(Dialog) to the child that created it. Tried subclassing but kept getting assert errors in CWnd::Attach that the window isn't null
if(m_tools.GetSafeHwnd()!=NULL)m_tools.DestroyWindow();
if(!m_tools.CreateEx(this->GetParent(),TBSTYLE_FLAT,WS_CHILD|WS_VISIBLE))
MessageBox(_T("Failed to create toolbar\n"));
if(-1==m_tools.LoadToolBar(IDR_TOOLBAR1))
MessageBox(_T("Bitmap not loaded"));
if(!m_tools.ShowWindow(SW_SHOW))
MessageBox(_T("NoShow"));
m_tools.ModifyStyle(NULL,CBRS_FLOATING | CBRS_TOOLTIPS | CBRS_FLYBY);
if(!m_tools.IsWindowVisible())
MessageBox(_T("Invisible"));
this->GetWindowRect(&rec);
rec.top-=100;rec.bottom=rec.top+16;rec.left-=100;rec.right-=100;
m_tools.MoveWindow(&rec);
modified 6-Feb-12 6:44am.
|
|
|
|
|
I'm not sure what you are trying to do here. What are you subclassing and why? You have a toolbar, so, as you click a button your dialog will receive a WM_COMMAND message, which you can then pass to the appropriate handler.
BTW please format your code a bit and put it inside a code block (via the code button above or with <pre> tags) so it's readable, like this:
if (m_tools.GetSafeHwnd()!= NULL)
m_tools.DestroyWindow();
if (!m_tools.CreateEx(this->GetParent(), TBSTYLE_FLAT | CBRS_FLOATING | CBRS_TOOLTIPS | CBRS_FLYBY))
MessageBox(_T("Failed to create toolbar\n"));
Much more readable.
Unrequited desire is character building. OriginalGriff
I'm sitting here giving you a standing ovation - Len Goodman
|
|
|
|
|
Exactly -- The dialog recieves the message. This involves coding a handler in Dialog class Seems Very very sloppy -- Much more elegant to have the parent redirect the WM_COMMANDS to the child.
My understanding is that subclassing does this. If I can get by the Assert errors
|
|
|
|
|
Fallen123 wrote: My understanding is that subclassing does this.
It's a while since I did any subclassing, and even longer for MFC, so I cannot say for sure. The Dialog receives the WM_COMMAND from the toolbar and should then either perform some action or call a function on the child class to perform the action; this may include passing the message direct to the child. I think this article[^] may be of some use in figuring out how it is designed to work.
Unrequited desire is character building. OriginalGriff
I'm sitting here giving you a standing ovation - Len Goodman
|
|
|
|
|
Okay article that fried me.
I was almost sure I couldn't pull this trick (and still thinking about it Trapping OnChildNotify ...).
I think I'll try to derive A Ctoolbar class with a wndproc handler - OnChildNotify firing messages on to my derived clistbox wndproc. It seems that might do it. All it would need is the original Window creating the toolbar.
If that fails
I'll probably just recreate my class Via CFrame, add the cListbox and toolbar. write the toolbar handler in Cframe ... and make the CFrame invisible using Defines
Still it seems that you should be able to rout the WndProc messages of a child to any handler you want. Then filter, and send unprocessed messages to the original handler.
One way or the other Thanx for your input
|
|
|
|
|
Fallen123 wrote: I think I'll try ...
I'll probably ...
I think you are just making more work and complications for yourself. I'm still not sure what you are trying to achieve, but handling command messages and using them to perform actions in child windows is basic stuff that all Windows applications perform by following the standard rules. You seem to be trying to create your own system that is outside of the Microsoft design, and are getting tied in knots trying to solve a problem that doesn't exist.
Unrequited desire is character building. OriginalGriff
I'm sitting here giving you a standing ovation - Len Goodman
|
|
|
|
|
Well it worked - Damn so simple
Now I can dynamically create/link any control without resorting to a frame class
directly to another - transparent to the Main dialog -- very useful
Derived a class from CToolbar toolbaradv
passed it the CWnd * pointer to ListboxAdv window -- m_Creator
Added handler
void toolBarAdv::OnNMClick(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMCLICK pNMClick = reinterpret_cast<LPNMCLICK>(pNMHDR);
m_Creator->SendMessage(10001,GetToolBarCtrl().GetHotItem());
*pResult = 0;
}
And caught the message in Derived listbox WndProc
All without having to touch the main parents message loop
And No "getting tied in knots trying to solve a problem that doesn't exist."
The problem has always been MS arrogance that "They have covered all the bases"
and not left room for expansion
A Class (or derived class) should be able to handle its messages pertaining to that class -- An options bar certainly qualifies -- you don't handle options local to the class externally --thats just bad widget design
This all got started because MS CListbox Doesn't allow access to resize its working area for the list
Example. A clistbox (no integral height),you add items and suddenly a scrollbar appears
(So a child scrollbar was Dynamically added and the listbox internals were recalculated to accomodate it --A variant of what I'm trying to do - Add a needed child) -- but try to find/modify the bloody routines that recalculate.
Basically I'm doing the same thing - Simply add a toolbar pertaining to options for the new derived listbox --Though not actually "in" but on in this case
PS in my dialogs I have 10 of these Listboxes -- think of the handling in main dialog message loop
Well nap time
|
|
|
|
|
I have a stack. When compiled with O3 it crashes. Works fine when compiled with -g . Any idea what is issue n how to debug it.
modified 5-Feb-12 13:35pm.
|
|
|
|
|
What are you talking about? compiler options, linker options? Clarify your question, it's not clear.
|
|
|
|
|
Compiler does ugly nice tricks when optimization is ON (on the other hand the debug build may hide some errors - e.g. it may initialize data you forgot to).
However we cannot help you more, without seeing your code.
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]
|
|
|
|
|
CPallini wrote: it may initialize data you forgot to
I hate it when it does that... 
|
|
|
|
|
Not unusual. The bare minimum you should provide is a call stack and the source code around the actual code that blows up (if possible).
Steve
|
|
|
|