Topic : Get and Modify Some Windows
Author : Barry Jacobsen
Page : 1

Well, checking the latest poll(might not be the latest by the time you read this, heh) it appears that people want tutorials more than anything else, so I figured what the heck, let's turn my code sample into a tutorial!  Okay now, for this tutorial we are going to make a program where you type in the Title Bar of an application, and it will give you the HWND, the Class type, and you can even minimize, maximize, and, for you win2k coders out there, make it translucent.

Fist, we start off by making a dialog box, name it IDD_MAIN
Add to it the following:
Two Edit controls, one named IDC_TITLE and another named IDC_RESULTS.  IDC_RESULTS should be multiline and have a vertical scrollbar.
Six Buttons, named IDC_GETINFO, IDC_MIN, IDC_MAX, IDC_TRANSLUCENT, IDC_VIS, and IDC_CLOSE.  Label them appropriately.
Also, make static text controls to label the two edit controls.

Okay, now on to the code.  Just like last time, I will give you all the code, then go through it step by step(though not quit as extensive, this is an advanced tutorial).

#include "resource.h"
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <string>
#include <list>
#include <algorithm>


#ifndef WS_EX_LAYERED
#define WS_EX_LAYERED           0x00080000
#define LWA_ALPHA               0x00000002
#endif // ndef WS_EX_LAYERED

typedef BOOL (WINAPI *lpfnSetLayeredWindowAttributes)(HWND hwnd, COLORREF crKey, BYTE bAlpha, DWORD dwFlags);
typedef UINT (WINAPI *lpfnRealGetWindowClass)(HWND  hwnd, LPTSTR pszType, UINT  cchType);


lpfnSetLayeredWindowAttributes m_pSetLayeredWindowAttributes;
lpfnRealGetWindowClass m_pRealGetWindowClass;
HWND hDialog = 0;
std::list<HWND> lstWins;
std::list<HWND> lstValWins;
std::string ResultsString;

void MakeWinTrans(HWND hWnd)
{
::SetWindowLong(hWnd, GWL_EXSTYLE, WS_EX_LAYERED);
m_pSetLayeredWindowAttributes(hWnd, NULL, 190, LWA_ALPHA);
}

void MakeWinVis(HWND hWnd)
{
::SetWindowLong(hWnd, GWL_EXSTYLE, WS_EX_LAYERED);
m_pSetLayeredWindowAttributes(hWnd, NULL, 255, LWA_ALPHA);
}

void Maximize(HWND hWnd)
{
::ShowWindow(hWnd, SW_MAXIMIZE);
}

void Minimize(HWND hWnd)
{
::ShowWindow(hWnd, SW_MINIMIZE);
}


void InitDlg(HWND hDlg)
{
HMODULE hUser32 = GetModuleHandle("USER32.DLL");

m_pSetLayeredWindowAttributes = (lpfnSetLayeredWindowAttributes)GetProcAddress(hUser32,

"SetLayeredWindowAttributes");
m_pRealGetWindowClass = (lpfnRealGetWindowClass)GetProcAddress(hUser32, "RealGetWindowClass");


if (NULL == m_pSetLayeredWindowAttributes)
{
::EnableWindow(::GetDlgItem(hDlg, IDC_TRANSLUCENT),false);
::EnableWindow(::GetDlgItem(hDlg, IDC_VIS),false);
}
else
{
::EnableWindow(::GetDlgItem(hDlg, IDC_TRANSLUCENT),true);
::EnableWindow(::GetDlgItem(hDlg, IDC_VIS),true);
}
}

BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
{
lstWins.push_front(hwnd);

    return TRUE;
}

void CheckName(HWND hWnd)
{
char cTitleToGet[255];
::GetWindowText(::GetDlgItem(hDialog, IDC_TITLE), cTitleToGet, 255);

char cCurrentTitle[255];
::GetWindowText(hWnd, cCurrentTitle, 255);

std::string StringToTest = cCurrentTitle;

if((strlen(cTitleToGet) > 0) && (static_cast<int>(StringToTest.find(cTitleToGet, 0)) >= 0)  && (::GetDlgItem(hDialog,

IDC_TITLE)!=hWnd))
lstValWins.push_front(hWnd);
}

void AddInfo(HWND hWnd)
{
char titlebuffer[255];
::GetWindowText(hWnd, titlebuffer, 255);

char classbuffer[255];
m_pRealGetWindowClass(hWnd, classbuffer, 255);

char *resultsbuffer = new char[strlen(titlebuffer) + strlen(classbuffer) + 255];
wsprintf(resultsbuffer, "Window: %i\r\nFull Title: %s\r\nClass: %s\r\n\r\n", hWnd, titlebuffer, classbuffer);

ResultsString.append(resultsbuffer);
}


BOOL CALLBACK DlgProc (HWND hwnd,
  UINT message,
  WPARAM wParam,
  LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
InitDlg(hwnd);
return TRUE;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDC_GETINFO:

lstWins.empty();
EnumWindows(EnumWindowsProc,NULL);

std::for_each(lstWins.begin(), lstWins.end(), CheckName);

ResultsString.empty();
std::for_each(lstValWins.begin(), lstValWins.end(), AddInfo);

::SetWindowText(::GetDlgItem(hDialog, IDC_RESULTS), ResultsString.c_str());
break;
case IDC_MAX:
std::for_each(lstValWins.begin(), lstValWins.end(), Maximize);
break;
case IDC_MIN:
std::for_each(lstValWins.begin(), lstValWins.end(), Minimize);
break;
case IDC_TRANSLUCENT:
std::for_each(lstValWins.begin(), lstValWins.end(), MakeWinTrans);
break;
case IDC_VIS:
std::for_each(lstValWins.begin(), lstValWins.end(), MakeWinVis);
break;
case IDC_CLOSE:
::SendMessage(hwnd, WM_CLOSE, NULL, NULL);
break;
}
return TRUE;
case WM_DESTROY:
::PostQuitMessage(0);
return TRUE;
case WM_CLOSE:
::DestroyWindow (hwnd);
return TRUE;
}
return FALSE;
}

int WINAPI WinMain
(HINSTANCE hInst, HINSTANCE hPrevInst, char * cmdParam, int cmdShow)
{
    hDialog = ::CreateDialog (hInst, MAKEINTRESOURCE (IDD_MAIN), 0, DlgProc);

::ShowWindow(hDialog, SW_SHOW);

MSG  msg;
while (::GetMessage(&msg, NULL, 0, 0))
{
if (!::IsDialogMessage (hDialog, & msg))
        {
            ::TranslateMessage ( & msg );
            ::DispatchMessage ( & msg );
        }
}

return msg.wParam;
}



Okay, now for some explanation.  If any of this is unclear, please e-mail me at BarryJ@cpp-home.com

#include "resource.h"
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <string>
#include <list>
#include <algorithm>

These are standard windows and STL(Standard Template Library Includes)

#ifndef WS_EX_LAYERED
#define WS_EX_LAYERED           0x00080000
#define LWA_ALPHA               0x00000002
#endif // ndef WS_EX_LAYERED

These #Defines deal with Translucent windows (Win2k Only)

typedef BOOL (WINAPI *lpfnSetLayeredWindowAttributes)(HWND hwnd, COLORREF crKey, BYTE bAlpha, DWORD dwFlags);
typedef UINT (WINAPI *lpfnRealGetWindowClass)(HWND  hwnd, LPTSTR pszType, UINT  cchType);

These are typedefs for two functions that aren't in older versions of windows.h, I load them from the library dynamicly.


lpfnSetLayeredWindowAttributes m_pSetLayeredWindowAttributes;
lpfnRealGetWindowClass m_pRealGetWindowClass;

Two varibles for the dynamicly loaded functions

HWND hDialog = 0;
A handle to our Dialog

std::list<HWND> lstWins;
std::list<HWND> lstValWins;

Lists to store all windows on the system, and the ones with the title we want.

std::string ResultsString;
The Text we put into the Results Edit Box

void MakeWinTrans(HWND hWnd)
{
::SetWindowLong(hWnd, GWL_EXSTYLE, WS_EX_LAYERED);
m_pSetLayeredWindowAttributes(hWnd, NULL, 190, LWA_ALPHA);
}

This function makes a window 75% transparent.

void MakeWinVis(HWND hWnd)
{
::SetWindowLong(hWnd, GWL_EXSTYLE, WS_EX_LAYERED);
m_pSetLayeredWindowAttributes(hWnd, NULL, 255, LWA_ALPHA);
}

Makes a window 100% visible

void Maximize(HWND hWnd)
{
::ShowWindow(hWnd, SW_MAXIMIZE);
}

Maximizes a window

void Minimize(HWND hWnd)
{
::ShowWindow(hWnd, SW_MINIMIZE);
}

Guess what?  It minimizes a window!

This code is called when the Dialog is first created:
void InitDlg(HWND hDlg)
{

HMODULE hUser32 = GetModuleHandle("USER32.DLL");

Gets a handle to the User32 Library

m_pSetLayeredWindowAttributes = (lpfnSetLayeredWindowAttributes)GetProcAddress(hUser32, "SetLayeredWindowAttributes");
m_pRealGetWindowClass = (lpfnRealGetWindowClass)GetProcAddress(hUser32, "RealGetWindowClass");

Load the functions we need

if (NULL == m_pSetLayeredWindowAttributes)
{
::EnableWindow(::GetDlgItem(hDlg, IDC_TRANSLUCENT),false);
::EnableWindow(::GetDlgItem(hDlg, IDC_VIS),false);
}
else
{
::EnableWindow(::GetDlgItem(hDlg, IDC_TRANSLUCENT),true);
::EnableWindow(::GetDlgItem(hDlg, IDC_VIS),true);
}

If the system is not win2k, disable the translucent and vis buttons.

BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
{
lstWins.push_front(hwnd);

    return TRUE;
}

This is called by windows when we need to build out list of all Windows, it just adds it to the list.


void CheckName(HWND hWnd)
{
char cTitleToGet[255];
::GetWindowText(::GetDlgItem(hDialog, IDC_TITLE), cTitleToGet, 255);

char cCurrentTitle[255];
::GetWindowText(hWnd, cCurrentTitle, 255);

std::string StringToTest = cCurrentTitle;

if((strlen(cTitleToGet) > 0) && (static_cast<int>(StringToTest.find(cTitleToGet, 0)) >= 0)  && (::GetDlgItem(hDialog,

IDC_TITLE)!=hWnd))
lstValWins.push_front(hWnd);
}

This function checks a window against what we are supposed to be looking for, and if it contains it, adds it to the Valid list.


void AddInfo(HWND hWnd)
{
char titlebuffer[255];
::GetWindowText(hWnd, titlebuffer, 255);

char classbuffer[255];
m_pRealGetWindowClass(hWnd, classbuffer, 255);

char *resultsbuffer = new char[strlen(titlebuffer) + strlen(classbuffer) + 255];
wsprintf(resultsbuffer, "Window: %i\r\nFull Title: %s\r\nClass: %s\r\n\r\n", hWnd, titlebuffer, classbuffer);

ResultsString.append(resultsbuffer);
}

This function adds the window, title, and class to the ResultsString which will then be put in the Results Edit box

I'll just do the specifics on the DlgProc Function:
case IDC_GETINFO:
lstWins.empty();
EnumWindows(EnumWindowsProc,NULL);

std::for_each(lstWins.begin(), lstWins.end(), CheckName);

ResultsString.empty();
std::for_each(lstValWins.begin(), lstValWins.end(), AddInfo);

::SetWindowText(::GetDlgItem(hDialog, IDC_RESULTS), ResultsString.c_str());
break;

Okay, this clears out the current list(incase there already was one, and checks each ones title to what the edit box says to.

  Then it adds the information into the ResultsString, and puts ResultsString into the Results Edit box.

case IDC_MAX:
std::for_each(lstValWins.begin(), lstValWins.end(), Maximize);
break;

Maximizes all valid Windows.

case IDC_MIN:
std::for_each(lstValWins.begin(), lstValWins.end(), Minimize);
break;

Minimizes all valid Windows.

case IDC_TRANSLUCENT:
std::for_each(lstValWins.begin(), lstValWins.end(), MakeWinTrans);
break;

Makes all valid Windows 75% visible.

case IDC_VIS:
std::for_each(lstValWins.begin(), lstValWins.end(), MakeWinVis);
break;

Makes all valid Windows 100% visible.

case IDC_CLOSE:
::SendMessage(hwnd, WM_CLOSE, NULL, NULL);
break;

Closes the app.



int WINAPI WinMain
(HINSTANCE hInst, HINSTANCE hPrevInst, char * cmdParam, int cmdShow)
{
    hDialog = ::CreateDialog (hInst, MAKEINTRESOURCE (IDD_MAIN), 0, DlgProc);

::ShowWindow(hDialog, SW_SHOW);

MSG  msg;
while (::GetMessage(&msg, NULL, 0, 0))
{
if (!::IsDialogMessage (hDialog, & msg))
        {
            ::TranslateMessage ( & msg );
            ::DispatchMessage ( & msg );
        }
}

return msg.wParam;
}

Standard WinMain for a DialogBox

By the way, don't get too crazy with making windows translucent, sometimes BAD things can happen...especially if you try to make EVERY window translucent...if you comment out the (strlen(cTitleToGet) > 0) part and click Get Info without typing anything...

Okay, I can e-mail you the source code to this if you would like, BarryJ@cpp-home.com.  Or if you have any questions, or suggestions.  Or Money that you want to send me...Especially the last one :)
Don't steal my code without credit :)
Copyright 2001 Barry Jacobsen


Page : 1