Hi, I appologize for a lack of specificity, but i'll try my best to explain what i want to do. I want to write a program that will run other programs within a single window, so that they're neatly organized.

For instance; I usually run about 3 Xterminals that i often lose track of behind many other windows. I would like to run a program that would keep those 3 xterms in a single window, sized and placed exactly how i want them.

If you can lead me in the right directly, i would greatly appreciate it. I'm just not sure where to even begin searching.

-Smed

Recommended Answers

All 12 Replies

This to me seemed like quite an interesting idea, so I had a go at it. The only real problem I had is painting problems (which can probably quite easily be sorted out). This sample program will assume that notepad.exe is already open before this program is executed. It then sets notepad as a child window of the main window I made. Heres the code:

#include <windows.h>

const char ClassName[] = "WndClassName";

HWND notepad;

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
   switch (msg) {
      case WM_CLOSE:
         {
            DestroyWindow(hwnd);
         }
         break;
      case WM_CREATE:
         {
            // Find notepad.exe window
            notepad = FindWindow("Notepad", NULL);

            // Check if notepad exists
            if (!notepad) {
               MessageBox(hwnd, "Notepad not open, closing", "Error",
                          MB_OK | MB_ICONERROR);
               DestroyWindow(hwnd);
            }

            // Set it as a child window
            SetParent(notepad, hwnd);

            // Resize and position it to make it visible
            SetWindowPos(notepad, NULL, 0, 0, 300, 300, NULL);
         }
         break;
      case WM_DESTROY:
         {
            PostQuitMessage(0);
         }
         break;
      default:
         return DefWindowProc(hwnd, msg, wParam, lParam);
   }
   return 0;
}

int CALLBACK WinMain(HINSTANCE hInstance,
            HINSTANCE hPrevInstance,
            LPSTR lpCmdLine,
            int nShowCmd) {
   HWND hwnd;
   WNDCLASSEX wc;
   MSG msg;

   wc.cbWndExtra = 0;
   wc.cbClsExtra = 0;
   wc.cbSize = sizeof WNDCLASSEX;
   wc.hbrBackground = (HBRUSH) COLOR_WINDOW;
   wc.hCursor = LoadCursor(NULL, IDC_ARROW);
   wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
   wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
   wc.hInstance = hInstance;
   wc.lpfnWndProc = WndProc;
   wc.lpszClassName = ClassName;
   wc.lpszMenuName = NULL;
   wc.style = 0;

   if (!RegisterClassEx(&wc)) {
      return 1;
   }

   hwnd = CreateWindowEx(
      WS_EX_APPWINDOW,
      ClassName,
      "Window Owner",
      WS_MINIMIZEBOX | WS_MAXIMIZEBOX|
      WS_SYSMENU | WS_CAPTION | WS_THICKFRAME,
      CW_USEDEFAULT, CW_USEDEFAULT,
      CW_USEDEFAULT, CW_USEDEFAULT,
      NULL, NULL, hInstance, NULL);

   if (!hwnd) {
      return 1;
   }

   ShowWindow(hwnd, nShowCmd);
   UpdateWindow(hwnd);

   while (GetMessage(&msg, NULL, 0, 0) > 0) {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
   }

   return static_cast<int>( msg.wParam );
}

I hope this gives you an idea of how to get started.

Thanks for the reply. I'm getting the following errors when I try to compile your code:

'FindWindowW' : cannot convert parameter 1 from 'const char [8]' to 'LPCWSTR'
'MessageBoxW' : cannot convert parameter 2 from 'const char [26]' to 'LPCWSTR'
'CreateWindowExW' : cannot convert parameter 2 from 'const char [13]' to 'LPCWSTR'

Any ideas?

As far as I see here it should be: notepad = FindWindow(NULL, "Notepad");

>'FindWindowW' : cannot convert parameter 1 from 'const char [8]' to 'LPCWSTR'
> 'MessageBoxW' : cannot convert parameter 2 from 'const char [26]' to 'LPCWSTR'
> 'CreateWindowExW' : cannot convert parameter 2 from 'const char [13]' to 'LPCWSTR'

Turn off the unicode character set, you can do this a few ways, either change your compiler settings, or at the very beginning of your code (before the includes) add:

#undef UNICODE

As far as I see here it should be: notepad = FindWindow(NULL, "Notepad");

Nope, the first parameter is the class name, which in this case is "Notepad", the second parameter is for the window name, which if you don't know, can be left as NULL, although I guess you could set it to the default "Untitled - Notepad", however the caption isn't guaranteed to be this, as once you open a file, it changes.

Rather than looking for notepad to already be opened, how would I create a new instance of notepad? I've looked into the CreateProcess funtion, but i'm not sure how to implement it in this situation.

This to me seemed like quite an interesting idea, so I had a go at it. The only real problem I had is painting problems.

No, you must not call SetParent() like this (FAQ)
Embedding is always done with OLE.

Embedding is always done with OLE.

... care to explain why? :?:

I've got a working program with a child window setup the way I want it, but now I want to make that child window an external program such as notepad. Any ideas?

#include <windows.h>
#include <tchar.h>

const char ClassName[] = "WndClassName";
static HINSTANCE ghInstance = NULL;

HWND notepad;

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
	HWND hChild;
   switch (msg) {
      case WM_CLOSE:
         {
            DestroyWindow(hwnd);
         }
         break;
      case WM_CREATE:
         {
			 hChild = CreateWindowEx(
                                NULL,
                               "EDIT",
                               "this is a child window",
                               WS_BORDER | WS_CHILD | WS_VISIBLE,
                               0, 0,
                               300, 300,
                               hwnd, NULL,
                               ghInstance,
                               NULL);
         }
         break;
      case WM_DESTROY:
         {
            PostQuitMessage(0);
         }
         break;
      default:
         return DefWindowProc(hwnd, msg, wParam, lParam);
   }
   return 0;
}

int CALLBACK WinMain(HINSTANCE hInstance,
            HINSTANCE hPrevInstance,
            LPSTR lpCmdLine,
            int nShowCmd) {
   HWND hwnd;
   WNDCLASSEX wc;
   MSG msg;

   wc.cbWndExtra = 0;
   wc.cbClsExtra = 0;
   wc.cbSize = sizeof WNDCLASSEX;
   wc.hbrBackground = (HBRUSH) COLOR_WINDOW;
   wc.hCursor = LoadCursor(NULL, IDC_ARROW);
   wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
   wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
   wc.hInstance = hInstance;
   wc.lpfnWndProc = WndProc;
   wc.lpszClassName = ClassName;
   wc.lpszMenuName = NULL;
   wc.style = 0;

   if (!RegisterClassEx(&wc)) {
      return 1;
   }


   hwnd = CreateWindowEx(
      WS_EX_APPWINDOW,
      ClassName,
      "Parent Window",
      WS_MINIMIZEBOX | WS_MAXIMIZEBOX|
      WS_SYSMENU | WS_CAPTION | WS_THICKFRAME,
      CW_USEDEFAULT, CW_USEDEFAULT,
      CW_USEDEFAULT, CW_USEDEFAULT,
      NULL, NULL, hInstance, NULL);

   if (!hwnd) {
      return 1;
   }


   ShowWindow(hwnd, nShowCmd);	
   UpdateWindow(hwnd);   


   while (GetMessage(&msg, NULL, 0, 0) > 0) {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
   }

   return static_cast<int>( msg.wParam );
}

I've got a working program with a child window setup the way I want it, but now I want to make that child window an external program such as notepad. Any ideas?

Thats what my original code did.. :idea: try doing what I said, the notepad window my not be visible at first, but thats because of painting problems, try minimizing and restoring the window, then you should see it. Heres a couple of screenshots showing before compiling & running the program, and after.

I know, I just don't like that you have to have notepad already running. Ideally I'd like to be able to click a "new" button and for it to create a new instance of notepad within the parent window.

That was just my example, if you code it yourself, you will probably be able to execute notepad before it opens.. remember my code was just an example of how to make an external program a child window within your window.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.