|
One way would be:
if (nCtlColor == CTLCOLOR_EDIT)
{
if (IDC_ANAOFFSET == ::GetWindowLong(*pWnd, GWL_ID))
{ Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Thanks. This and the previous reply are exactly what I needed. One more related question; what is the best way to cause a WM_COLOR (or something that kicks the OnCtlColor handler) message to be sent? Specifically, I need to cause color changes when certain events occur. So, the event handlers need to cause the OnCtlColor handler to run and perform the color change. Is SendMessage the best way to do that or something else?
Wayne
|
|
|
|
|
I would just use Invalidate().
Set a flag or whatever you use to indicate what color it should be then use Invalidate() to mark a
window for repainting. You can call it on a specific control or an entire dialog/window:
// Mark MyEditCtl for repainting
MyEditCtl.Invalidate(TRUE);
For situations where you need the repaint to occur immediately, you can follow the Invalidate()
call with UpdateWindow(). For UI controls this generally isn't necessary.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Also, note that for buttons, the same messages apply BUT for pushbuttons, the button has to be
owner drawn for it to have any effect.
It's not as simple as with edit controls
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Well (hopefully) one more question. The color change works when the edit control is NOT in read-only mode. However what I really want is for it to be in read-only mode. When in read-only the OnCtlColor handler never gets called for the control that I want to change. How do I get around that?
Wayne King
|
|
|
|
|
When the edit control is in read-only mode, the WM_CTLCOLOR message, the control
type is CTLCOLOR_STATIC so you can add something like this to your OnCtlColor
handler:
else if (nCtlColor == CTLCOLOR_STATIC)
{
...
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Thanks again. That did it. You have been immensely helpful. I have still another sort-of related question. How do you change the text font? Is there a difference in methods depending upon whether it's an edit or button control? I've searched the message board, microsoft, etc. but can't seem to hit on the right criteria to find an answer.
Thanks again,
Wayne
|
|
|
|
|
You're welcome
To set the font, create a font and call SetFont() on the control to set its font.
Example:
CFont m_EditFont;
...
m_EditFont.CreateFont....
...
MyEdit.SetFont(&m_EditFont);
Mark
*edit* fixed a sample code typo
Last modified: 11mins after originally posted --
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Is there an easy to specify the font size without getting buried in the science of font attributes? I created the font this way and played with the height but it seems to be ignored. No matter what I set the height to there is no change. All I need to do is use some standard font and adjust the size to fit my needs.
Font2.CreateFont(500, // nHeight
0, // nWidth
0, // nEscapement
0, // nOrientation
FW_NORMAL, // nWeight
FALSE, // bItalic
FALSE, // bUnderline
0, // cStrikeOut
ANSI_CHARSET, // nCharSet
OUT_DEFAULT_PRECIS, // nOutPrecision
CLIP_DEFAULT_PRECIS, // nClipPrecision
DEFAULT_QUALITY, // nQuality
FIXED_PITCH | FF_SWISS, // nPitchAndFamily
"Arial");
Wayne
|
|
|
|
|
I think the easiest way to avoid the details of calculating an appropriate size is to start with
the default font (in a dialog, that's set by the dialog) and adjust the height up or down from
the default.
You can use CWnd::GetFont() and CFont::GetLogFont() to get a LOGFONT for the dialog's font.
Adjust the height in that struct, create the edit control font (using CFont::CreateFontIndirect()
and set the control's font to that font.
Not you need to do this in OnInitDialog() or later since CWnd::GetFont() requires a valid HWND.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
If you just want to change the face color of the button, you can use CTLCOLOR_BTN in OnCtlColor same as that you do for edit control.
- NS -
|
|
|
|
|
In general you can use of these messages:
WM_CTLCOLORBTN for button
WM_CTLCOLORDLG for dialog
WM_CTLCOLOREDIT for edit
WM_CTLCOLORLISTBOX for listbox
WM_CTLCOLORSCROLLBAR for scrollbar
WM_CTLCOLORSTATIC for static control.
|
|
|
|
|
I created a IE browser process using the MFC createprocess function.
Later on in my main program, I want to set focus on and put the IE broswer process as the top window using SetWindowPos function. It tried this and it doesn't work when SetWindowPos is called. If I launch a MS paint program using the same functionality, the SetWindowPos function does bring the MS paint window to the top and with focus.
Here is some sample code.
Create the IE process and get the window handle to it.
HANDLE hProcess = NULL;
PROCESS_INFORMATION processInfo;
STARTUPINFO startupInfo;
::ZeroMemory(&startupInfo, sizeof(startupInfo));
startupInfo.cb = sizeof(startupInfo);
if(::CreateProcess("C:\\Program files\\Internet Explorer\\iexplore.exe",
"",
NULL, // process security
NULL, // thread security
FALSE, // no inheritance
0, // no startup flags
NULL, // no special environment
NULL, // default startup directory
&startupInfo,
&processInfo))
{ /* success */
Sleep(1500);
::EnumWindows(&EnumWindowsProc, processInfo.dwThreadId);//Iterate all windows
hProcess = processInfo.hProcess;
} /* success */
int CALLBACK EnumWindowsProc(HWND hwnd, LPARAM param)
{
DWORD pID;
DWORD TpID = GetWindowThreadProcessId(hwnd, &pID);//get process id
if (TpID == (DWORD)param)
{
apphwnd=hwnd;//hwnd is the window handle
return false;
}
return true;
}
// later on in the program I try to bring the window for the IE process on top and into focus
if(apphwnd!=NULL)//check for window handle
{ // window exists already
CString windowText ;
CWnd* window = CWnd::FromHandle(
apphwnd);
if (window != NULL )
{
BOOL res =::SetWindowPos(apphwnd, HWND_TOP, 0, 0, 0, 0,SWP_NOMOVE | SWP_SHOWWINDOW); window->SetFocus();
}
The result of this is the IE window does not get put on top.
I then trie the same code with the MS paint program process (at "C:\\WINDOWS\\system32\\mspaint.exe") and it does work. The window gets put on top. What do I need to do to get IE to respond to my call ?
Stephen Da-Terminator
SCI Solutions
|
|
|
|
|
What happens if you pass the PROCESS_INFORMATION.dwProcessId to EnumWindows() instaed of the thread Id?
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Thanks for the reply. That didn't work either (same result) but I found out how to make it work. Apparently multiple windows (within IE) had the same processId and I needed to find the main window for IE in order to get the right handle. So it works no with the code below.
Stephen
//Function to enumerate all windows.
int CALLBACK EnumWindowsProc(HWND hwnd, LPARAM param)
{
DWORD pID;
DWORD TpID = GetWindowThreadProcessId(hwnd, &pID);//get process id
if (pID == (DWORD)param)
{
TCHAR windowClass[256];
CString windowText, msg, aclass ;
CWnd* window = CWnd::FromHandle(
hwnd);
if (window != NULL )
{
window->GetWindowText( windowText);
GetClassName(hwnd, windowClass, sizeof(windowClass));
msg.Format(_T("processId %d: windowclass %s: windowtext %s \n"),pID,windowClass, windowText);
TRACE(msg);
}
aclass = windowClass ;
if (apphwnd == NULL && aclass.CompareNoCase("IEFrame") == 0)
{
apphwnd=hwnd;//hwnd is the window handle
apID = pID ;
}
}
return true;
}
Stephen Da-Terminator
SCI Solutions
|
|
|
|
|
i want to pass a struct as the parameter to my thread function.
typedef struct tagTHREADPARMS {
CWnd* pWnd;
CEvent* pKillEvent;
CEvent* pOutputEvent;
CMultithreadingTestDlg* pDlg;//error
} THREADPARMS;
i got plenty of syntax errors, such as:
error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
what's the cause?
|
|
|
|
|
Make sure your structure and thread are member of same class or have been declared globally.
I hope you have type casted the pointer to the structure as LPVOID in the CreateThread() or BeginThread()
|
|
|
|
|
yes, they are both declared globally.
is it possible that i'm missing some header file, because the exact same error occured when i declared a CEvent object, however, the error is gone after i include "afxmt.h"
|
|
|
|
|
it seems like if i change CMultithreadingTestDlg* pDlg to CDialog*pDlg, the error is gone...
but i need a pointer to CMultithreadingTestDlg class...
|
|
|
|
|
You just do a forward declaration of CMultithreadingTestDlg, where you declared the structure (if it is in any header file). And in the cpp file you include the header of CMultithreadingTestDlg.
- NS -
|
|
|
|
|
I am coding an application which has a menu and a document. The menu has few radio buttons and check boxes. Based on user selection on the menu, I need to display description of what user's choices mean [few lines of text for each selection] on the document.
I know CEdit class has GetLine() GetLineCount() to get the lines in a multi line document. But how do I display text sequentially on the document using CEdit class?
|
|
|
|
|
I might not get the true meaning of your question, but you can provide the user with 'tool tips' (yellow box with text) to explain what each item does. Would that help with what you are trying to accomplish?
John P.
|
|
|
|
|
You can use SetWindowText . Also you can use ReplaceSel to insert text in the current cursor position if nothing is selected.
|
|
|
|
|
Hi,
I am working on a MDI application. I use CDaoDatabase (so I include AFXDAO.h) for my application. After doing some manipulation wiht the data, I close my dialog box, which has a "Close" button with the ID "IDCANCEL". So, when I close my dialog box, the whole application is getting closed.
But the dialogs which are not using this afxdao.h is working fine. That means, it closes only the dialog and not the application.
Could anyone, please help me in this regard.
PS: I am using VC++ 6.0.
Thanks in advance.
Regards
saravana
|
|
|
|
|
Put a breakpoint on CMainFrame::OnClose()...then in debug mode look at the call stack to understand why you reach that point of the code.
Hope it helps
Russell
|
|
|
|