|
Not sure I follow you. The buttons behave properly as a group in the UI, i.e. after selecting one you can arrow back & forth to switch selection, etc.
As for the value of the radio variables, they never change throughout the lifetime of the dialog. If I initialize them with 0, 1 or 123456798, that's what they exit the dialog with. Am I missing something?
|
|
|
|
|
Discussions around the topic are still under way.
I do not remember exactly, but at some point in time, I had to to add the WS_GROUP attribute to all the radio buttons, create all the variables, then I had to remove the WS_GROUP attribute from all but the first radio
button. Do not ask why. I cannot explain. It just happenned like that. After that, it worked properly.
A lot of my friends say it is an ancient design bug, and it has been around as long as Visual Studio has existed. There are signals that actually VS7 propagates that behaviour.
Long story short: try to do what I did, then share ... your experience
SkyWalker
|
|
|
|
|
I understand what you mean, but WS_GROUP is a window style, and I'm using html in the associated .htm file to create the controls rather than the CDialog oriented method that uses the .rc file.
If this was a CDialog, I could have implemented it faster than it took me to type the messages.
Apparently the html dialog is voodoo - I can't seem to get much info on it anywhere, and folks here don't seem to be familiar with it, either...
|
|
|
|
|
Promise to keep an eye on the topic
SkyWalker
|
|
|
|
|
See here[^] maybe it is some helpful to you
|
|
|
|
|
Hi, Whitesky.
I appreciate the link, and it looks like cool stuff. However, the problem I'm looking to solve is getting the data member variables updated in DoDataExchange. If you have any insights on that, they would be most appreciated.
Thanks,
|
|
|
|
|
|
Hi,
When I insert a button on a toolbar (OnCreate & OnSize) it shows as it should. However, after the call to OnPaint() where I do some painting on the client area of the toolbar, the button disappears. It is still there (I can click on it), but it is not showing. I tried clipping the client region so that it did not overlap the button rectangle, but... Also, I tried
::SendMessage(m_hWnd, TB_HIDEBUTTON,FALSE,FALSE);
inside the OnPaint() - BeginPaint(), but did not work either.
Anyone?
Tanx in advance,
Murillo
|
|
|
|
|
Try ModifyStyle( 0, WS_CLIPCHILDREN )
- NS -
|
|
|
|
|
Did not work either. I tried just after creating the button
|
|
|
|
|
Could you show the code snippet?
- NS -
|
|
|
|
|
Hello NS,
I am working on Erik Thompsom's toolbar tutorial (http://www.codeproject.com/atl/ietoolbartutorial.asp).
After making some modifications to Erik's code, I added a static control to the right of the button and managed to change bk color, text color and so on, which happens inside OnPaint()->BeginPaint(). However, after doing this the button doesn't get repainted. It is still there, since it is responding to mouse clicks. I tried many things, from clipping the (m_hWnd) toolbar's client rect so that it wouldn't overlap the button, to trying to paint only the static control (m_ReadWnd) which is a child window for the m_hWnd. I will show you three functions: OnCreate, OnSize and OnPaint.
<br />
LRESULT CMFToolbar::OnCreate(UINT uMsg,WPARAM wParam, LPARAM lParam, BOOL& bHandled)<br />
{<br />
SendMessage(m_hWnd, TB_SETEXTENDEDSTYLE, 0, (LPARAM)TBSTYLE_EX_MIXEDBUTTONS);<br />
<br />
SendMessage(m_hWnd, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON),0);<br />
<br />
SendMessage(m_hWnd, TB_SETMAXTEXTROWS, 1, 0L);<br />
<br />
TCHAR* pCaption = _T("Cotação - Yahoo Finance");<br />
int iIndex = ::SendMessage(m_hWnd, TB_ADDSTRING, 0, (LPARAM)pCaption);<br />
<br />
HICON hMotley = LoadIcon(_Module.GetResourceInstance(), MAKEINTRESOURCE(IDI_MOTLEY));<br />
m_hImageList = ImageList_Create(16,16,ILC_COLOR16,1,0);<br />
int iImageIndex = ImageList_AddIcon(m_hImageList,hMotley);<br />
DestroyIcon(hMotley);<br />
<br />
::SendMessage(m_hWnd, TB_SETIMAGELIST, 0, (LPARAM)m_hImageList);<br />
<br />
TBBUTTON Button;<br />
ZeroMemory((void*)&Button, sizeof(TBBUTTON));<br />
Button.idCommand = IDM_GETQUOTE;<br />
Button.fsState = TBSTATE_ENABLED;<br />
Button.fsStyle = BTNS_BUTTON | BTNS_AUTOSIZE | BTNS_SHOWTEXT;<br />
Button.dwData = 0;<br />
Button.iString = iIndex;<br />
Button.iBitmap = 0;<br />
::SendMessage(m_hWnd, TB_INSERTBUTTON, 0, (LPARAM)&Button);<br />
<br />
<br />
RECT rect = {0,0,0,0};<br />
m_EditWnd.Create(m_hWnd, rect, NULL, WS_CHILD|WS_VISIBLE,WS_EX_CLIENTEDGE);<br />
m_EditWnd.SetFont(static_cast<HFONT>(GetStockObject(DEFAULT_GUI_FONT)));<br />
<br />
<br />
RECT rect2 = {0,0,0,0};<br />
<br />
m_ReadWnd.Create(m_hWnd, rect2, NULL,WS_CHILD|WS_VISIBLE|WS_EX_CLIENTEDGE);<br />
m_ReadWnd.SetFont(static_cast<HFONT>(GetStockObject(DEFAULT_GUI_FONT)));<br />
m_ReadWnd.SetWindowText("Text on STATIC OBJECT");<br />
<br />
<br />
return 0;<br />
}<br />
<br />
LRESULT CMFToolbar::OnSize(UINT uMsg,WPARAM wParam, LPARAM lParam, BOOL& bHandled)<br />
{<br />
<br />
RECT wndRect, btnRect;<br />
<br />
RECT fixedRect = {0,0,50,20};<br />
<br />
GetClientRect(&wndRect);<br />
::SendMessage(m_hWnd, TB_GETITEMRECT, 0, (LPARAM)&btnRect);<br />
<br />
SendMessage(TB_SETINDENT,55);<br />
<br />
m_EditWnd.MoveWindow(&fixedRect, FALSE); <br />
<br />
wndRect.left += btnRect.right + 300;<br />
<br />
wndRect.right -= 100;<br />
<br />
m_ReadWnd.MoveWindow(&wndRect, FALSE);<br />
<br />
return 0;<br />
}<br />
<br />
LRESULT CMFToolbar::OnPaint(UINT uMsg,WPARAM wParam, LPARAM lParam, BOOL& bHandled)<br />
{<br />
<br />
PAINTSTRUCT ps, ps2;<br />
HDC hDC = NULL;<br />
HDC hDC2= NULL;<br />
RECT test_rect = {100,100,100,20};<br />
RECT bk_rect = {100,100,100,20};<br />
HRGN hRgn = NULL;<br />
HRGN hRgn2 = NULL;<br />
HBRUSH hBr = CreateSolidBrush(RGB(255,0,0));<br />
HBRUSH hBr2 = CreateSolidBrush(RGB(0,0,255));<br />
<br />
::GetClientRect(m_hWnd,&test_rect);<br />
::GetClientRect(m_ReadWnd,&bk_rect);<br />
<br />
hRgn2= CreateRectRgn(test_rect.right/2,test_rect.top+10,test_rect.right-900,test_rect.bottom-5);<br />
<br />
hRgn = CreateRectRgn(bk_rect.left+200,bk_rect.top,bk_rect.right-100,bk_rect.bottom);<br />
<br />
hDC2 =::BeginPaint(m_hWnd,&ps2);<br />
hDC =::BeginPaint(m_ReadWnd,&ps);<br />
<br />
::SelectClipRgn(hDC2,hRgn2);<br />
::SelectClipRgn(hDC,hRgn);<br />
<br />
::SetTextColor(hDC,RGB(255,255,255));<br />
<br />
::SetBkColor(hDC,RGB(255,0,0));<br />
::FillRect(hDC2,&test_rect,hBr2); <br />
::FillRect(hDC,&bk_rect,hBr);<br />
<br />
::TextOut( hDC, 0, 0, _T("Some Text"),9 );<br />
<br />
::EndPaint(m_ReadWnd,&ps);<br />
::EndPaint(m_hWnd,&ps2);<br />
<br />
<br />
<br />
return 0;<br />
}<br />
If I do not treat the WM_PAINT message, the button appears. If I treat, it does not.
One other thing: you may notice that I have to BeginPaint(..) on both the parent window (m_hWnd) and the child window (m_ReadWnd), although I just want to paint the child. If I don't BeginPaint the parent, IE crashes...
Sorry for the long message. I can send you printscreen images of the toolbar so you can have a better idea if necessary.
Thank you NS
- Mfranco -
|
|
|
|
|
mfranco_neto wrote: hDC2 =::BeginPaint(m_hWnd,&ps2);
hDC =::BeginPaint(m_ReadWnd,&ps);
I wonder why you should call the BeginPaint for static control inside the OnPaint of the parent. Did you try excluding this one? BeginPaint is something different from normal GetDC. You can learn more about it from MSDN.
And to change the color of a static control, CTLCOLOR_STATIC handling will be enough, right? Did you try that?
From your code in the OnPaint, I understand you just want to change the static control's color properties, right?
- NS -
|
|
|
|
|
Hummm.... You mean that I should write another MESSAGE_HANDLER for WM_PAINT on the message map of the static object?
I went through MSDN reading about GetDC and BeginPaint, and somewhere (I think) is said that with GetDC I must treat WM_ERASEBACKGROUND. But since I don't know how, I was using BeginPaint...
I am a hardware engineer, so I am not that familiar with C++ or Windows programming. I have spent the last few weeks, at night, trying to customize this toolbar...
I feel very lost right now... I just want to change bkgnd/text color of the static object and make the button on the toolbar appear... seems easy, but...
I don't really understand what you mean by "I wonder why you should call the BeginPaint for static control inside the OnPaint of the parent"...
Do you think that the button is being erased because BeginPaint erases the toolbar bkgnd? If you do, how should I erase the bkgnd so that I don't erase the button?
Sorry for these silly questions, but MSDN isn't of big help for beginners, we relly on you guys..
ThanX
mfranco
|
|
|
|
|
OK... You don't need to handle the any paint messages to change the color of a static text control. You just handle OnCtrlColor().
mfranco_neto wrote: I feel very lost right now...
Don't think like that... Now you know the method that do not lead to static text color handling... Next time you won't waste time in this way.
I am not sure about the results caused by calling BeginPaint inside OnPaint of another window. It is not desirable, because BeginPaint is for optimized painting.
HBRUSH CMyDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) <br />
{<br />
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);<br />
<br />
if (pWnd->GetDlgCtrlID() == IDC_MYSTATIC)<br />
{<br />
pDC->SetTextColor(RGB(255, 0, 0));<br />
pDC->SetBkMode(TRANSPARENT);<br />
hbr = GetStockObject( NULL_BRUSH );<br />
}<br />
<br />
return hbr;<br />
}
The above code may help you.
- NS -
|
|
|
|
|
Thanks a lot NS!!! I hope that it helps me!!
Although your answer is very complete, as I am just beginning to understand everything related to C++ and Windows, could you please extend your assistance to a few more questions?
NS17 wrote: HBRUSH CMyDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
-> CMyDlg == "MyToolbar" class?
-> I assume it is called inside the message map of the toolbar (...HANDLER(WM_CTLCOLOR...,OnCtrlColor)). if so, where do I pass the parameters?
NS17 wrote: HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
-> CDialog... wasn't it CMyDlg?? -> I know this may seem a silly question and you may wonder what is a person who does not know the difference trying to build a toolbar??
NS17 wrote: return hbr;
-> Where does this brush return to, if the function is called from inside a message map (if it is the case)?
Thank you once again, for I have spent the last few week nights trying to understand everythng...
|
|
|
|
|
NS17 wrote: HBRUSH CMyDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
Compiling...
MFToolbar.cpp
C:\Murphy\Temp\MFToolbar.cpp(150) : error C2653: 'CDialog' : is not a class or namespace name
C:\Murphy\Temp\MFToolbar.cpp(150) : error C2065: 'OnCtlColor' : undeclared identifier
????????????????????
|
|
|
|
|
I am sorry for the delay... I was not here for some days.
mfranco_neto wrote: C:\Murphy\Temp\MFToolbar.cpp(150) : error C2653: 'CDialog' : is not a class or namespace name
In your case the CDialog should be replaced with your class' base class.
As far as I know i will be CToolBarCtrl.
OK... You have to do the following steps...
In .h file add
afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
between //{{AFX_MSG(CMyToolBar) and //}}AFX_MSG
like:
afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
OK?
Now in .cpp add
ON_WM_CTLCOLOR()
between //{{AFX_MSG_MAP(CMyToolBar) and //}}AFX_MSG_MAP
like
ON_WM_CTLCOLOR()
OK?
Now place the code that I sent you before...
HBRUSH CMyToolBar::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CToolBarCtrl::OnCtlColor(pDC, pWnd, nCtlColor);
if (pWnd->GetDlgCtrlID() == IDC_MYSTATIC)
{
pDC->SetTextColor(RGB(255, 0, 0));
pDC->SetBkMode(TRANSPARENT);
hbr = GetStockObject( NULL_BRUSH );
}
Note: The CMyToolBar should be replaced with your class name. And your base class name should be placed in the place of CToolBarCtrl if it not the same.
IDC_MYSTATIC is the ID of your static text.
The return brush will be used for the painting the background of the static text control. Here we are returning NULL brush, so the background will be transparent. And the text color is changed to RGB(255,0,0) (RED).
Please know that this method is used in dialogs. And I did not tested this in such a toolbar (means a Toolbar for IE).
Any way GOOD LUCK...
- NS -
|
|
|
|
|
Hi NS,
Thank you for this "step-by-step tutorial"... . It's just amazing...
I started reading the book "Programming Windows API - 5th ed", by Petzold, to understand a little bit more about WinAPI, and stop asking very silly questions
I will try your solution and see what happens...
Once again, thank you very much. I know that it will help a lot other programmers which go through this FAQ.
|
|
|
|
|
I am not able to see my control list (by mistake i have press the del button) so that i can add control in my dialog box,What option should i use to display it again.
Thanks
|
|
|
|
|
am not sure what u mean.
Open any dialog in resources. Right click on any existing menu bar or tool bar in the msdev. a popup menu will appear. In it click controls.
nave
|
|
|
|
|
Does a function have to be a member of a class? Can it stand alone "classless?" If so, is it available to be used in any other class or function?
Likewise, does a data variable have to be a member of a class? If not, is it available to be used in any other class or function?
|
|
|
|
|
|
Hi, Oliver.
You can declare functions outside of your class just as you did in C, and they'll be globally available.
Additionally, there are times when you might want the function to be a member of your class, but you wish to avoid the implicit "this" param, such as when you're creating a callback function. In this case, you can declare the function static, and call it with explcit scope resolution, i.e. CMyClass::GlobalFunction(param1, param1).
The same applies to variables. You can declare them outside of a class (I typically use the g_ with the Hungarian to know that it's global, i.e. CString g_strText). You can also make them static members of your class, which for instance is the method employed in CFile for the open and create mode flages (CFile::modeRead, etc.).
Hope this helps.
|
|
|
|
|
When using CHttpConnection in my MFC program, is there a way to make the connection to Proxy server persistent instead of closing after every request? Or can I have to manually put the field into the header. For example I have:
------------------------- SAMPLE CODE ------------------------
CInternetSession session;
CHttpConnection* pConnection = NULL;
CHttpFile* pFile1 = NULL;
CString strHeaders = _T("Content-Type: image/jpeg\r\nProxy-Connection: Keep-Alive\r\nUser-Agent: MyProgram/1.0\r\n");
char buffer[BUFSIZZ];
UINT nBytesRead;
pConnection = session.GetHttpConnection("www.test.com", (INTERNET_PORT)80 );
for (i = 0; i < 30; i++) {
pFile1 = pConnection->OpenRequest(CHttpConnection::HTTP_VERB_GET, "/", NULL, 1, NULL, NULL, INTERNET_FLAG_DONT_CACHE);
pFile1->SendRequest(strHeaders);
nBytesRead = 0;
nBytesRead = pFile1->Read(buffer, BUFSIZZ - 1);
buffer[nBytesRead] = '\0';
pFile1->Close();
delete pFile1;
}
------------------------------------------------------------------
However, when I run the code and do "netstat" I couldn't see any TCP connection with the proxy, even though the number of bytes read was non zero.
Btw, I noticed that the header produced using CHttpConnection/CHttpFile (captured using ethereal) says it's HTTP 1.0 instead of 1.1, will this create any problems with proxy server?
|
|
|
|
|