Avatar billede mrandersdk Nybegynder
09. juli 2005 - 21:57 Der er 10 kommentarer og
1 løsning

styring af 2 vinduer

Jeg har lavet et lille script der åbner to vinduer og man kan så lukke dem igen (JIR!! lidt simpelt men man skal jo starte et sted). Mir problem er at for at gøre så de ikke begge lukker når jeg lukker det ene, har jeg lavet på callbacks, mit spørgsmål er om der ikke er en måde jeg kan afgøre hvilket vindue msg kommer fra så jeg slipper for to af dem. Ved ikke helt hvordan måkse noget med at lave to forskellige hwnd når jeg "creater" mine vinduer. Håber mit spørgsmål giver mening.

Her er min kode:



// INCLUDES /////////////////////////////////////////////////
#define WIN32_LEAN_AND_MEAN  // STOP MFC

#include <windows.h>
#include <windowsx.h>
#include <stdio.h>
#include <math.h>

// DEFINES //////////////////////////////////////////////////
#define WINDOW_CLASS_NAME "WINCLASS!"

// GLOBALS //////////////////////////////////////////////////

bool stop = FALSE;

// FUNCTIONS ////////////////////////////////////////////////
LRESULT CALLBACK WindowProc(HWND hwnd,
                            UINT msg,
                            WPARAM wparam,
                            LPARAM lparam)
{

// main message handler
PAINTSTRUCT ps;        // used in WM_PAINT
HDC hdc;            // handle to device context

switch(msg)
{
case WM_CREATE:
    {
        return 0;
    } break;
case WM_PAINT:
    {
        hdc = BeginPaint(hwnd,&ps);

        EndPaint(hwnd,&ps);

        return 0;
    } break;
case WM_DESTROY:
    {
        if (stop = TRUE)
        {
            PostQuitMessage(0);
        }
        else
        {
            stop = TRUE;
        }

        return 0;
    } break;

default:break;
}  // end switch


// hvis der kommer en message vi ikke har med
return (DefWindowProc(hwnd, msg, wparam, lparam));

} // end WinProc





// 2

LRESULT CALLBACK WindowProc2(HWND hwnd2,
                            UINT msg2,
                            WPARAM wparam2,
                            LPARAM lparam2)
{

// main message handler
PAINTSTRUCT ps2;        // used in WM_PAINT
HDC hdc2;            // handle to device context

switch(msg2)
{
case WM_CREATE:
    {
        return 0;
    } break;
case WM_PAINT:
    {
        hdc2 = BeginPaint(hwnd2,&ps2);

        EndPaint(hwnd2,&ps2);

        return 0;
    } break;
case WM_DESTROY:
    {
       
        if (stop = TRUE)
        {
            PostQuitMessage(0);
        }
        else
        {
            stop = TRUE;
        }

        return 0;
    } break;

default:break;
}  // end switch


// hvis der kommer en message vi ikke har med
return (DefWindowProc(hwnd2, msg2, wparam2, lparam2));

} // end WinProc2





// WINMAIN //////////////////////////////////////////////////

int WINAPI WinMain(HINSTANCE hinstance,
                  HINSTANCE hprevinstance,
                  LPSTR lpcmdline,
                  int ncmdshow)
{

// Winclass
WNDCLASSEX winclass;
HWND hwnd;
MSG msg;

    winclass.cbSize = sizeof(WNDCLASSEX);
    winclass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
    winclass.lpfnWndProc = WindowProc;
    winclass.cbClsExtra = 0;
    winclass.cbWndExtra = 0;
    winclass.hInstance = hinstance;
    winclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    winclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    winclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
    winclass.lpszMenuName = NULL;
    winclass.lpszClassName = "WINCLASS";
    winclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

    if (!RegisterClassEx(&winclass))
    return 0;


if (!(hwnd =CreateWindowEx(NULL,
        "WINCLASS",
        "1",
        WS_OVERLAPPEDWINDOW | WS_VISIBLE,
        100,100,
        400,400,
        NULL,
        NULL,
        hinstance,
        NULL)))
return(0);





// Winclass2
HWND hwnd2;
MSG msg2;

    winclass.cbSize = sizeof(WNDCLASSEX);
    winclass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
    winclass.lpfnWndProc = WindowProc2;
    winclass.cbClsExtra = 0;
    winclass.cbWndExtra = 0;
    winclass.hInstance = hinstance;
    winclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    winclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    winclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
    winclass.lpszMenuName = NULL;
    winclass.lpszClassName = "WINCLASS2";
    winclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

    if (!RegisterClassEx(&winclass))
    return 0;


if (!(hwnd2 =CreateWindowEx(NULL,
        "WINCLASS2",
        "2",
        WS_OVERLAPPEDWINDOW | WS_VISIBLE,
        500,100,
        400,200,
        NULL,
        NULL,
        hinstance,
        NULL)))
return(0);


// main loop
while(TRUE)
{

if (PeekMessage(&msg,NULL,0,0,PM_REMOVE) | PeekMessage(&msg2,NULL,0,0,PM_REMOVE))
    {

    if (msg.message == WM_QUIT)
    {
        break;
    }
   

    TranslateMessage(&msg);
    DispatchMessage(&msg);

    TranslateMessage(&msg2);
    DispatchMessage(&msg2);

// main game here

    } // end if

} // end while

} // end WinMain
Avatar billede bertelbrander Novice
09. juli 2005 - 22:15 #1
Du burde kunne bruge samme WindowProc til begge vinduer, første parameter i kaldet fortæller netop hvilket vindue beskeden er for.

Denne linie er sansynlig vis forkert (begge tilfælde):
        if (stop = TRUE)

Du bør kunne bruge GetMessage i din message loop, som det er nu vil dit program æde alt cpu tid.
Avatar billede mrandersdk Nybegynder
09. juli 2005 - 23:44 #2
mener du at i min hwnd er der hvilket vidue beskeden er fra ? Hvis ja hvordan får jeg så den ene switch til at dele det op i de beskeder der kommer fra det ene og dem fra det andede?
Avatar billede bertelbrander Novice
09. juli 2005 - 23:54 #3
Hvis du laver HWND hwnd; og HWND hwnd2; fra WinMain om til globale variable, og kalder dem hwnd1 og hwnd2, kan du i din WindowProc lave:

if(hwnd == hwnd1)
{
  // It's the first window
}
else if(hwnd == hwnd2)
{
  // It's the second window
}
else
{
  // What
}

Din message loop kunne se sådan ud:
  MSG Msg;
  while(GetMessage(&Msg, 0, 0, 0xFFFF) > 0)
  {
      TranslateMessage(&Msg);
      DispatchMessage(&Msg);
  }
Avatar billede mrandersdk Nybegynder
10. juli 2005 - 00:05 #4
smart, tror det virker, leger lige lidt med det og vender så tilbage. Tror bare jeg har lidt problemer med hvordan parametrerne bliver sendt rundt, er lige startet på c++.
Avatar billede bertelbrander Novice
10. juli 2005 - 00:09 #5
Jeg lavede lige et eksempel. Det skulle gerne lave et vindue (1) med rød baggrund og et andet (2) med grøn baggrund:

// INCLUDES /////////////////////////////////////////////////
#define WIN32_LEAN_AND_MEAN  // STOP MFC

#include <windows.h>
#include <windowsx.h>
#include <stdio.h>
#include <math.h>

// DEFINES //////////////////////////////////////////////////
#define WINDOW_CLASS_NAME "WINCLASS!"

// GLOBALS //////////////////////////////////////////////////

bool stop = false;

HWND hwnd1;
HWND hwnd2;

// FUNCTIONS ////////////////////////////////////////////////
LRESULT CALLBACK WindowProc(HWND hwnd,
                            UINT msg,
                            WPARAM wparam,
                            LPARAM lparam)
{

  // main message handler
  PAINTSTRUCT ps;        // used in WM_PAINT
  HDC hdc;            // handle to device context

  switch(msg)
  {
  case WM_CREATE:
      {
          return 0;
      } break;
  case WM_PAINT:
      {
          hdc = BeginPaint(hwnd,&ps);
          RECT R;
          GetClientRect(hwnd, &R);
          if(hwnd == hwnd1)
          {
              FillRect(hdc, &R, CreateSolidBrush(RGB(255, 0, 0)));
          }
          else if(hwnd == hwnd2)
          {
              FillRect(hdc, &R, CreateSolidBrush(RGB(0, 255, 0)));
          }
          else
          {
              MessageBox(hwnd, "Ups, wrong window!", "Whatever", MB_OK);
          }
          EndPaint(hwnd,&ps);
          return 0;
      } break;
  case WM_DESTROY:
      {
          if (stop)
          {
              PostQuitMessage(0);
          }
          else
          {
              stop = true;
          }

          return 0;
      } break;

  default:break;
}  // end switch


// hvis der kommer en message vi ikke har med
  return (DefWindowProc(hwnd, msg, wparam, lparam));

} // end WinProc

// WINMAIN //////////////////////////////////////////////////

int WINAPI WinMain(HINSTANCE hinstance,
                  HINSTANCE hprevinstance,
                  LPSTR lpcmdline,
                  int ncmdshow)
{

  // Winclass
  WNDCLASSEX winclass;

    winclass.cbSize = sizeof(WNDCLASSEX);
    winclass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
    winclass.lpfnWndProc = WindowProc;
    winclass.cbClsExtra = 0;
    winclass.cbWndExtra = 0;
    winclass.hInstance = hinstance;
    winclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    winclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    winclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
    winclass.lpszMenuName = NULL;
    winclass.lpszClassName = "WINCLASS";
    winclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

    if (!RegisterClassEx(&winclass))
    return 0;


  if (!(hwnd1 =CreateWindowEx(NULL,
                              "WINCLASS",
                              "1",
                              WS_OVERLAPPEDWINDOW | WS_VISIBLE,
                              100,100,
                              400,400,
                              NULL,
                              NULL,
                              hinstance,
                              NULL)))
      return(0);





// Winclass2

    winclass.cbSize = sizeof(WNDCLASSEX);
    winclass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
    winclass.lpfnWndProc = WindowProc;
    winclass.cbClsExtra = 0;
    winclass.cbWndExtra = 0;
    winclass.hInstance = hinstance;
    winclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    winclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    winclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
    winclass.lpszMenuName = NULL;
    winclass.lpszClassName = "WINCLASS2";
    winclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

    if (!RegisterClassEx(&winclass))
    return 0;


  if (!(hwnd2 =CreateWindowEx(NULL,
          "WINCLASS2",
          "2",
          WS_OVERLAPPEDWINDOW | WS_VISIBLE,
          500,100,
          400,200,
          NULL,
          NULL,
          hinstance,
          NULL)))
      return(0);

  MSG Msg;
  while(GetMessage(&Msg, 0, 0, 0xFFFF) > 0)
  {
      TranslateMessage(&Msg);
      DispatchMessage(&Msg);
  }

  return 0;

} // end WinMain
Avatar billede mrandersdk Nybegynder
10. juli 2005 - 00:19 #6
tak skal du ha'. Jeg har også lige lavet lidt, det er sikkert ikke så pænt (man er jo en newb), men det kan jo være nogen kan få glæde af det:

// INCLUDES /////////////////////////////////////////////////
#define WIN32_LEAN_AND_MEAN  // STOP MFC

#include <windows.h>
#include <windowsx.h>
#include <stdio.h>
#include <math.h>

// DEFINES //////////////////////////////////////////////////
#define WINDOW_CLASS_NAME "WINCLASS!"

// GLOBALS //////////////////////////////////////////////////

HWND hwnd1;
HWND hwnd2;


// FUNCTIONS ////////////////////////////////////////////////
LRESULT CALLBACK WindowProc(HWND hwnd,
                            UINT msg,
                            WPARAM wparam,
                            LPARAM lparam)
{

// main message handler
PAINTSTRUCT ps;        // used in WM_PAINT
HDC hdc;            // handle to device context

switch(msg)
{
case WM_CREATE:
    {
        return 0;
    } break;
case WM_PAINT:
    {
        hdc = BeginPaint(hwnd,&ps);

        EndPaint(hwnd,&ps);

        return 0;
    } break;
case WM_DESTROY:
    {

            if (hwnd == hwnd1)
            {
                hwnd1 = NULL;
            }
            else if (hwnd == hwnd2)
            {
                hwnd2 = NULL;
            }


            if (hwnd1 == NULL && hwnd2 == NULL)
            {
                PostQuitMessage(0);
            }
           

        return 0;
    } break;

default:break;
}  // end switch


// hvis der kommer en message vi ikke har med
return (DefWindowProc(hwnd, msg, wparam, lparam));

} // end WinProc



// WINMAIN //////////////////////////////////////////////////

int WINAPI WinMain(HINSTANCE hinstance,
                  HINSTANCE hprevinstance,
                  LPSTR lpcmdline,
                  int ncmdshow)
{

// Winclass
WNDCLASSEX winclass;

MSG msg;

    winclass.cbSize = sizeof(WNDCLASSEX);
    winclass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
    winclass.lpfnWndProc = WindowProc;
    winclass.cbClsExtra = 0;
    winclass.cbWndExtra = 0;
    winclass.hInstance = hinstance;
    winclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    winclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    winclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
    winclass.lpszMenuName = NULL;
    winclass.lpszClassName = "WINCLASS";
    winclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

    if (!RegisterClassEx(&winclass))
    return 0;


if (!(hwnd1 =CreateWindowEx(NULL,
        "WINCLASS",
        "1",
        WS_OVERLAPPEDWINDOW | WS_VISIBLE,
        100,100,
        400,400,
        NULL,
        NULL,
        hinstance,
        NULL)))
return(0);


if (!(hwnd2 =CreateWindowEx(NULL,
        "WINCLASS",
        "2",
        WS_OVERLAPPEDWINDOW | WS_VISIBLE,
        500,100,
        400,200,
        NULL,
        NULL,
        hinstance,
        NULL)))
return(0);


// main loop
while(TRUE)
{

if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
    {

    if (msg.message == WM_QUIT)
    {
        break;
    }
   

    TranslateMessage(&msg);
    DispatchMessage(&msg);



// main game here

    } // end if

} // end while

} // end WinMain


Grunden til jeg bruger PeekMessage er fordi det stod i en bog, den startede med GetMessage, men skiftede så til PeekMessage, det var noget med den skulle være mere "live".

Men smid et svar, det var en stor hjælp.
Avatar billede bertelbrander Novice
10. juli 2005 - 00:25 #7
Prøv at starte taskmanageren/joblisten når dit program kører, så kan du se at dit program bruger ca 100% cpu tid.

Man bruger normalt kun PeekMessage hvis man vil checke om der er noget i køen, men ikke ønsker at vente hvis der ikke ligger nogen besked klar. I dit eksempel spørger du igen og igen og igen.

Jeg samler ikke på point.
Avatar billede mrandersdk Nybegynder
10. juli 2005 - 00:37 #8
ja jeg har lagt mærke til den bruger 99 %, men der må da være en grund til at bogen siger man skal bruge den istedet for getmessage, bogen handler egentlig om at lave spil kan det have noget med sagen at gøre ?
Avatar billede bertelbrander Novice
10. juli 2005 - 00:42 #9
Ja, det kan godt have noget med sagen at gøre.
I et spil vil man typisk lave en masse grafik og fra tid til anden checke om der er nye beskeder og så fortsætte med grafikken. I spil ønsker man ikke at vente på beskeder, men vil fortsætte med noget andet, hvis der ikke er bekeder der skal håndteres.
I dit eksempel laves der ikke andet end at vente på besker, og så er der ingen grund til at bruge PeekMessage.
Avatar billede mrandersdk Nybegynder
10. juli 2005 - 00:44 #10
ja ok, men regner med at der bliver bygget videre på dette eksempel så det er vigtigt at jeg beholder peekmeassage, men tak for rådet det er meget rart at vide når jeg engang skal prøve at lave noget andet.
Avatar billede mrandersdk Nybegynder
10. juli 2005 - 15:10 #11
jeg lukker det. Endnu en gang tak for hjælpen
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester