codeguru的对话,解决定制cfiledialog工具条的问题

mfc 专栏收录该内容
2 篇文章 0 订阅
 
Feoggou
February 18th, 2008, 09:49 AM
Hi! I have some questions.. How can I change the text of a control of a CFileDialog common dialog (after I have derived it)? I have tried in OnInitDialog() of my CMyFileDlg to use SetWindowText() and SetControlText() but does nothing. Why here it does not work and in a CMyFontDlg derived from CFontDlg common dlg works? and what can I do in order to work?

please help..

zerver
February 18th, 2008, 10:14 AM
It has a rather strange design, so you have to call GetParent().
CWnd* pParent = GetParent();
pParent->SetDlgItemText(edt1, "hello"); // this is the "file name" edit box

CWnd* pWnd = pParent->GetDlgItem(lst2); // file list is in a child window
CListCtrl* wndLst1 = (CListCtrl*)(pWnd->GetDlgItem(1)); // here it is...

VictorN
February 18th, 2008, 10:18 AM
The text of what control do you want to change?
SetWindowText works good for the controls on your "customized" template.
GetParent->SetWindowText (as well as SetControlText, of course!) works for the controls on the original CFileDialog template.
Could you show your code?

Feoggou
February 21st, 2008, 09:05 AM
thanks, that was it! I work on the default template, I did not create another one and GetParent()-> SetWindowText() changes the text of the dialog's titlebar and GetParent()->SetDlgItemText() changes the text of a child window's text.

Anyway, I have another question: if there is SetWindowText ()(and GetDlgItem()) and SetDlgItemText(), then why does SetControlText() exist?

and I have some problems with handling the toolbars, if you'd like to help:
as it is seen, the CFileDialog dialog has 2 toolbars: a vertical one and a horizontal one. The main reason why I work with the CFileDialog is that I want to translate the text in my language. Well, it seems that I can't get any button of the toolbar, I don't even know how they are built and what exactly they are: CToolBar?? I have tried to use methods of CToolBar (like SetButtonInfo) but assertion errors occur (for example, here VERIFY(pBar->DefWindowProc(TB_GETBUTTON, nIndex, (LPARAM)pButton)); for which I do not know the cause). Mabey it is not a CToolBar. But then what is it?

And how can I handle the elements of the toolbar from the top of the dialog? how can I handle that toolbar?

please Help!

VictorN
February 21st, 2008, 09:27 AM
Anyway, I have another question: if there is SetWindowText ()(and GetDlgItem()) and SetDlgItemText(), then why does SetControlText() exist?Just to make your life easier! Read the documentation and never mind CFileDialog child/parent problems! ;)
... I have tried to use methods of CToolBar (like SetButtonInfo) but assertion errors occur ...
And how can I handle the elements of the toolbar from the top of the dialog? how can I handle that toolbar?

please Help!How did you access the toolbar? Can you show your code?

Feoggou
February 21st, 2008, 09:38 AM
well, in dlgs.h there is //
// Controls
//
#define ctl1 0x04A0 I have used CToolBar* pCtl = (CToolBar*)GetParent()->GetDlgItem(ctl1); to access it and if I used pCtl->ShowWindow(FALSE); And the area which had the buttons "Desktop", "My Documets", ... has become clear: so that must be the toolbar.

VictorN
February 21st, 2008, 09:57 AM
Have you tried Spy++ to get this "toolbar" class? Perhaps, it is not a toolbat at all?

Feoggou
February 21st, 2008, 11:20 AM
I have found 2 toolbars (ToolbarWindow32) which have the parent the window with "Save as" caption. Theese 2 must be.

one of them has the id 0x04A0 and the other 0x0440. The curios thing is that in dlgs.h file the item 0x0440 is presented as being static text (stc1)

VictorN
February 21st, 2008, 11:46 AM
stc1 is the "Label for the lst1 list box". It is used in the old-style dialog only!

Well, what code did you use with the pCtl to get the assertion errors and where did you use it?

Feoggou
February 21st, 2008, 12:05 PM
the following functions call _GetButton and thus go to VERIFY(pBar->DefWindowProc(TB_GETBUTTON, nIndex, (LPARAM)pButton));- Here is the error:

GetItemID, GetButtonInfo, GetButtonText, GetButtonStyle. May be others as well, I haven't tried all of them.

I have also tried RECT rect = pCtl->GetBorders(); but rect's members become 0xCDCDCDCD

I don't know if there is a thing from CControlBar/CToolBar that works here:(

VictorN
February 21st, 2008, 12:10 PM
Here is the error:

GetItemID, GetButtonInfo, GetButtonText, GetButtonStyle. Where "here"? :confused: :mad:
If you don't want to show your code that does fail then there is nothing to ask/discuss! :cool:

I don't know if there is a thing from CControlBar/CToolBar that works here:(What "works here"? How does it work here? Can you show the code to compare what does work and what does not?

Feoggou
February 21st, 2008, 01:29 PM
BOOL CMyFileDlg::OnInitDialog()
{
CFileDialog::OnInitDialog();

// TODO: Add extra initialization here

HWND hWnd = GetParent()->m_hWnd;
OldWndProc = (WNDPROC)SetWindowLong(hWnd, GWL_WNDPROC, (LONG)NewWndProc);
GetParent()->SetWindowTextW(L"New Text here");

//from here I modified things to other controls, that work
...................................................................................

CToolBar* pCtl = (CToolBar*)GetParent()->GetDlgItem(ctl1);
UINT u = pCtl->GetItemID(0);

return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}

All I have tried to do with pCtl ended in error.
For example, UINT u = pCtl->GetItemID(0);
in bartool.cppUINT CToolBar::GetItemID(int nIndex) const
{
ASSERT_VALID(this);
ASSERT(::IsWindow(m_hWnd));

TBBUTTON button;
_GetButton(nIndex, &button);
return button.idCommand;
}
Here, _GetButton(nIndex, &button); goes in
void CToolBar::_GetButton(int nIndex, TBBUTTON* pButton) const
{
CToolBar* pBar = (CToolBar*)this;
VERIFY(pBar->DefWindowProc(TB_GETBUTTON, nIndex, (LPARAM)pButton));
// TBSTATE_ENABLED == TBBS_DISABLED so invert it
pButton->fsState ^= TBSTATE_ENABLED;
}And DefWindowProc(TB_GETBUTTON, nIndex, (LPARAM)pButton) returns 0 which means, error!

VictorN
February 22nd, 2008, 03:59 AM
1. Does the same happen if you access the "main" toolbar (at the top of dialog)?
2. Did you try to step in the DefWindowProc to see where it fails?

Feoggou
February 22nd, 2008, 11:38 AM
1. Does the same happen if you access the "main" toolbar (at the top of dialog)? Yes, the same happens with the horizonal toolbar which is at the top of the dialog. Some interesting things about this toolbar are that:
1. I could not paint on it (I have tried to draw a rectangle with white brush, but nothing happened (I have also used MessageBox() after to ensure it does not repaint after);
2. I could not hide it (I used ShowWindow(FALSE) but nothing happened);
3. I used GetClassName() function on it (it's id is 0x0440) and the string returned was "Static" while with Spy++ it is "ToolbarWindow32"

2. Did you try to step in the DefWindowProc to see where it fails? it goes in LRESULT CWnd::DefWindowProc(UINT nMsg, WPARAM wParam, LPARAM lParam)
{
if (m_pfnSuper != NULL)
return ::CallWindowProc(m_pfnSuper, m_hWnd, nMsg, wParam, lParam);

WNDPROC pfnWndProc;
if ((pfnWndProc = *GetSuperWndProcAddr()) == NULL)
///the condition is true and returns the following
return ::DefWindowProc(m_hWnd, nMsg, wParam, lParam);
else
return ::CallWindowProc(pfnWndProc, m_hWnd, nMsg, wParam, lParam);
}And about return ::DefWindowProc(m_hWnd, nMsg, wParam, lParam);, I cannot step into this function, it only returns 0.

VictorN
February 22nd, 2008, 11:49 AM
Have a look at this thread (http://groups.google.com/group/microsoft.public.vc.mfc/browse_frm/thread/eef1eec5b1a696ca/1159baf18990947a?hl=en&lnk=st&q=Cfiledialog+toolbar+buttons#1159baf18990947a)

Feoggou
February 23rd, 2008, 11:30 AM
Yes, I have seen that the top toolbar can be handled in this method (using GetWindow, then in a loop GetNextWindow). But I don't understand: how that I cannot handle it well with GetDlgItem, but in the method above I can?

And second, I have put that code in my OnInitDialog, and it added an image (I have created one for the toolbar) on the toolbar that is on the top of the window. I have commented the break; command to see what happens for the second toolbar (the vertical one, from the left of the dialog). But nothing happens; GetButtonCount returns 0, GetButton() does not modify it's parameter (LPTBBUTTON). But I get no assertion error.

Please tell me how that it works with the method u have shown and does not work with the simple GetDlgItem (I have also tried CToolBarCtrl* pCtl = (CToolBarCtrl*)GetParent()->GetDlgItem(ctl1); instead of CToolBar* pCtl = (CToolBar*)GetParent()->GetDlgItem(ctl1); but it seems that for none of them I can get the number of buttons (GetButtonCount returns 0) in this way. And please tell me how I can handle the vertical toolbar items.

VictorN
February 25th, 2008, 04:33 AM
Only a guess: have you tried to get the id of the "standard" toolbar in the SDI application?
Have you tried to get the toolbar pointer/HWND using GetDlgItem() for the "standard" toolbar in the SDI application and compare it with the correct toolbar handle?

Feoggou
February 26th, 2008, 11:12 AM
Only a guess: have you tried to get the id of the "standard" toolbar in the SDI application?
Have you tried to get the toolbar pointer/HWND using GetDlgItem() for the "standard" toolbar in the SDI application and compare it with the correct toolbar handle?
Now I have tried them, and it seems that I cannot get in a SDI application the toolbar in any way, if I do not have the m_wndToolBar. Not using GetDlgItem (it has the ID 59392 and it seems it returns NULL if I try GetDlgItem) and with GetWindow and GetNextWindow I have found 4 things which sounded like toolbars, but none of them had this ID. Their class name was AfxControlBar80ud.

And, by the way, I have found how to get the buttons in the vertical toolbar: I subclassed it, and handled it's messages, and in it's methods I could get some of its functionality (like GetButton, GetButtonCount, SetButtonInfo). I do not understand why, but it worked that. I will ask about theese problems in the future, if I will need them, but now I have had enough of getting the toolbar!

Thanks for your help.

VictorN
February 26th, 2008, 11:22 AM
You are welcome and I'm glad you have solved your problem!
Could you share your solution (including obtaining the toolbar handle/pointer, subclassing and getting button info)?

Feoggou
February 26th, 2008, 11:28 AM
here?

Feoggou
February 26th, 2008, 11:34 AM
you mean, here, in the forum?

VictorN
February 26th, 2008, 11:59 AM
Yes, some code snippets would be interesting and useful for other people in the future. ;)

Feoggou
February 28th, 2008, 05:25 AM
So, here it is what I did in order to be able to get a button from the vertical toolbar, of my file dialog CMyFileDialog:

1. I derived a control from CToolBarCtrl, named CMyToolBarCtrl.
2. I added a member to CMyFileDialog, CMyToolBarCtrl m_Toolbar;
3. In the OnInitDialog of the CMyFileDialog I added the following code: CWnd* Child = GetParent()->GetWindow(GW_CHILD);
while (Child)
{
TCHAR clsName[16];
GetClassName(Child->m_hWnd, clsName, 16);
if (lstrcmp(clsName, L"ToolbarWindow32")==0 && Child->GetDlgCtrlID()==0x04A0)
{
m_ToolBar.SubclassWindow(Child->m_hWnd);
break;//do not loop any more, after the job is done
}

Child = Child->GetNextWindow();
} So, what I did up here is:
- I sought for the vertical toolbar handle (the vertical one has the ID 0x04A0, which I found with Spy++, the horizontal one has the ID 0x0440), through all the child windows of the dialog.
- When I found the right toolbar, I subclassed the m_ToolBar control so that it will handle that toolbar and handle messages in CMyToolBarCtrl class.

4. Now I added the code which could not be handled in OnInitDialog of CMyFileDialog for the toolbar, in a member of CMyToolBarCtrl. In my case, it had to be a function called early, when the dialog is shown. I chose OnNcPaint.
5. I added the following code in the OnNcPaint function, and here is how it looks:void CMyToolBar::OnNcPaint()
{
TBBUTTON tbbutton;
TBBUTTONINFO tbi;
this->GetButton(0, &tbbutton);//here we modify the first button

tbi.dwMask = TBIF_TEXT;//we change only the text
tbi.pszText = L"My New Text Here";
tbi.cbSize = sizeof(tbi);

this->SetButtonInfo(tbbutton.idCommand, &tbi);//add the info
}
And now the first button, who first had the text "My Recent Documents", now has the text "My New Text Here"

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 扫一扫,分享海报

©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值