|
Hi all. Is there some API or standard function to call to retrive the current name of the program running? Something like GetCurrentProcessId(), maybe something like GetCurrentProgramName() or something of the sort. Google and Yahoo dont seem to help and i dont know where to begin this sort of search. Any suggestions? Thanx in advance.
|
|
|
|
|
|
Do you want to know current name of your program or other programs?
|
|
|
|
|
Isn't there an easy way, e.g. a CWnd base member function, that can be used to change a window's foreground or background color? I have two cases; in one I would like to change the background color of an edit control, in another I would like to change the color of a button. From what I have seen so far it seems like I have to create new classes derived from, in this case, the edit and button classes so that they can handle a WM_ERASE and do the necessary painting. I must not understand something because this seems way more complicated than it would seem and I don't want to head down the wrong path.
Thanks,
Wayne King
|
|
|
|
|
Edit control, easy. Button control, you're on your own
For edit controls, you can add a handler (in the parent dialog/window) for the WM_CTLCOLOR message.
In response to that message, return a handle to a brush that the system will use to paint the background.
Here's an example that sets all edit controls in a dialog to green text on red background:
RedBrush.CreateSolidBrush(RGB(0xFF,0x00,0x00));
...
BEGIN_MESSAGE_MAP(CMyDialog, CDialog)
ON_WM_CTLCOLOR()
END_MESSAGE_MAP()
...
HBRUSH CMyDialog::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CMyDialog::OnCtlColor(pDC, pWnd, nCtlColor);
if (nCtlColor == CTLCOLOR_EDIT)
{
pDC->SetTextColor(RGB(0x00,0xFF,0x00));
pDC->SetBkColor(RGB(0xFF,0x00,0x00));
hbr = RedBrush;
}
return hbr;
}
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
So that would set ALL edit controls in CMyDialog to those colors? How can I set just one control; say one with an ID of IDC_ANAOFFSET?
|
|
|
|
|
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...
|
|
|
|