Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

BlazeX

Alter Hase

  • »BlazeX« ist der Autor dieses Themas

Beiträge: 478

Wohnort: DD

Beruf: Maschinenbau-Student

  • Private Nachricht senden

1

14.04.2009, 09:20

WinAPI: Problem mit der Fenstergröße

Hi Leute!
Ich habe ein Problem mit AdjustWindowRect.
Es liefert falsche Werte: Für gewollte 800x600 bekomme ich am Ende 792x572.

Kennt einer vor euch eine zuverlässige Funktion die wenigstens unter Vista, XP und 200 läuft?

n0_0ne

1x Contest-Sieger

  • Private Nachricht senden

2

14.04.2009, 09:38

Hi,
ich kenne die WinApi nicht wirklich gut, aber wie es aussieht, ist bei der Größenangabe wohl der Rahmen des Fensters schon mit drin... Ich denke bei unterschiedlichen Auflösungen müsste der auch (in Pixel) immer gleich groß bleiben, weshalb du vielleicht einfach nur +8 bei der Breite und +28 bei der Höhe draufrechnen musst, damit es passt... Ist aber wohl nur eine übergangslösung, bis jemand hier die Richtige Funktion postet :P

killmichnich

unregistriert

3

14.04.2009, 09:43

hast dus schonmal mit GetWindowRect() probiert

Anonymous

unregistriert

4

14.04.2009, 09:47

Hi,

das ist ne relativ einfache Angelegenheit, wenn KEIN Menü da ist, ansonsten machs so:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
void control::set_client_size (const size_t& width, const size_t& height)
{
    switch (used_unit_)
    {
    case unit::pixel: 
        {
            set_client_size__pixel (width, height);
        } break;
    case unit::dialog: 
        // [...]

    }
}

void control::set_client_size__pixel (const size_t& width, const size_t& height)
{
    if (handle_ == nullptr || !::IsWindow (handle_))
        throw exception::runtime (window::status::uninitialised, id_);

    ::RECT rect_window;
    if (!::GetWindowRect (handle_, &rect_window))
        throw exception::runtime (window::status::system_error, id, _ ("receiving window rectangle"), ::GetLastError ());
    
    ::RECT rect_client;
    if (!::GetClientRect (handle_, &rect_client))
        throw exception::runtime (window::status::system_error, id, _ ("receiving client rectangle"), ::GetLastError ());
    
    if (!::MoveWindow (handle_, 
                       rect_window.left, 
                       rect_window.top, 
                       rect_window.right - rect_window.left + (width - rect_client.right), 
                       rect_window.bottom - rect_window.top + (height - rect_client.bottom), 
                       true))
        throw exception::runtime (window::status::system_error, id, _ ("moving window"), ::GetLastError ());
}


p.s.: das geht ab Windows 1 ;)

BlazeX

Alter Hase

  • »BlazeX« ist der Autor dieses Themas

Beiträge: 478

Wohnort: DD

Beruf: Maschinenbau-Student

  • Private Nachricht senden

5

14.04.2009, 10:00

GetWindoeRect dachte ich auch schn, aber ich brauch die Größe bevor ich das Fenster erstelle :x

Hier ist mal ein Test-Programm mit meiner eigenen Funktion: AdjustStandardWindowRect: Passt die Größe für Fenster ohne Menü an.

C-/C++-Quelltext

1
//nicht mehr wichtig



Könnten bitte mal alle probieren und das Ergebnis und das OS posten! :idea:

Anonymous

unregistriert

6

14.04.2009, 10:05

Das ist doch Blödsinn was du da machst!

Mach mal das WS_VISIBLE weg, das hat beim Hauptfenster sowieso nichts zu suchen, da dies erst nach der Initialisierung der anderen Controls in WM_CREATE dargestellt werden soll durch, na wer erräts? Genau: ShowWindow!

Generell initialisiert man Fenster sowieso mit Position, Höhe und Breite 0 und setzt diese Angaben erst in WM_SIZE, welche auch vor dem Anzeigen aufgerufen wird.

Du machst dir dein Leben unnötig schwer, würde ich sowas da runter coden, hätte ich jetzt schon einen Krückstock bei den Brüchen die man sich da holt.

BlazeX

Alter Hase

  • »BlazeX« ist der Autor dieses Themas

Beiträge: 478

Wohnort: DD

Beruf: Maschinenbau-Student

  • Private Nachricht senden

7

14.04.2009, 10:34

So genehm?

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
void AdjustStandardWindowRect(HWND hWindow, RECT& WindowSizeRect)
{
    //Außen- und Innenrahmen

    RECT WindowRect, ClientRect;

    //Erstmal klein zum testen

    MoveWindow(hWindow, 0, 0, 400, 300, FALSE);

    //Maße holen

    GetWindowRect(hWindow, &WindowRect);
    GetClientRect(hWindow, &ClientRect);

    //Größe anpassen

    WindowSizeRect.right += WindowRect.right - ClientRect.right;
    WindowSizeRect.bottom+= WindowRect.bottom - ClientRect.bottom;

    //Positin an Größe anpassen

    WindowSizeRect.left   = GetSystemMetrics(SM_CXSCREEN)/2 - WindowSizeRect.right /2;
    WindowSizeRect.top    = GetSystemMetrics(SM_CYSCREEN)/2 - WindowSizeRect.bottom/2;

    //Fenster neue Größe geben

    MoveWindow(hWindow, WindowSizeRect.left, WindowSizeRect.top,
        WindowSizeRect.right, WindowSizeRect.bottom, FALSE);
}

Anonymous

unregistriert

8

14.04.2009, 10:45

Nein, nicht genehm, denn das was du da machst ist Strunks. Nennen wir das Kind beim Namen.

In den Code den du gepostet hast, fehlte ja selbst die Hauptschleife. Dann meine Frage: Warum hast du dann eine Fensterprozedur, wenn du die Nachrichten nicht verarbeiten kannst mangels fehlender Hauptschleife? Ist doch Nonsens!

Hier ich hab dir mal auf die Schnelle ein Beispiel runtergehauen was optimal ist und dir mal zeigt wie es richtig geht! Mit Struktur und ohne wirren Kram. Allein schon dein Gemische von TCHAR und WCHAR ist mehr als nur gefährlich (ebenso wie falsche Fehlercodes an Windows zurückliefern.)

main.hpp

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#if !defined (main_hpp_included)
#define main_hpp_included

#if defined (_MSC_VER) && (_MSC_VER >= 1020)
    #pragma once
#endif

// ///////////////////////////////////////////////////////////////////////////

// headers

// ///////////////////////////////////////////////////////////////////////////

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



// ///////////////////////////////////////////////////////////////////////////

// functions

// ///////////////////////////////////////////////////////////////////////////


/// //////////////////////////////////////////////////////////////////////////

/// Setzt die Größe des Clients eines Fensters.

///

/// \param hwnd:

///     Fenster dessen Größe angepasst werden soll.

/// \param width:

///     Breite in Pixel.

/// \param height:

///     Höhe in Pixel

///

/// //////////////////////////////////////////////////////////////////////////

void set_client_size (::HWND hwnd, const size_t& width, const size_t& height);

/// //////////////////////////////////////////////////////////////////////////

/// Fensterprozedur.

///

/// \param hwnd:

///     Handle auf das Fenster.

/// \param message:

///     Zu verarbeitende Nachricht.

/// \param wParam:

///     Zusatzdaten für die Nachricht.

/// \param lParam:

///     Zusatzdaten für die Nachricht.

///

/// //////////////////////////////////////////////////////////////////////////

::LPARAM WINAPI window_procedure (::HWND hwnd, ::UINT message, ::WPARAM wParam, ::LPARAM lParam);

/// //////////////////////////////////////////////////////////////////////////

/// Implementierung von der Fensternachricht: WM_CREATE

///

/// \param hwnd:

///     Handle auf das Fenster.

/// \param create_struct:

///     Erstellungsdaten.

///

/// //////////////////////////////////////////////////////////////////////////

bool on_create (::HWND hwnd, ::CREATESTRUCT* create_struct);

/// //////////////////////////////////////////////////////////////////////////

/// Implementierung von der Fensternachricht: WM_DESTROY

///

/// \param hwnd:

///     Handle auf das Fenster.

///

/// //////////////////////////////////////////////////////////////////////////

void on_destroy (::HWND hwnd);

/// //////////////////////////////////////////////////////////////////////////

/// Implementierung von der Fensternachricht: WM_PAINT

///

/// \param hwnd:

///     Handle auf das Fenster.

///

/// //////////////////////////////////////////////////////////////////////////

void on_paint (::HWND hwnd);

/// //////////////////////////////////////////////////////////////////////////

/// Implementierung von der Fensternachricht: WM_SIZE

///

/// \param hwnd:

///     Handle auf das Fenster.

/// \param state:

///     Zu verarbeitender Status.

/// \param width:

///     Neue Breite des Fensters.

/// \param height:

///     Neue Breite des Fensters.

///

/// //////////////////////////////////////////////////////////////////////////

void on_size (::HWND hwnd, ::UINT state, int width, int height);

#endif


main.cpp

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// ///////////////////////////////////////////////////////////////////////////

// headers

// ///////////////////////////////////////////////////////////////////////////

#include "main.hpp"


// ///////////////////////////////////////////////////////////////////////////

// functions

// ///////////////////////////////////////////////////////////////////////////


/// //////////////////////////////////////////////////////////////////////////

/// Setzt die Größe des Clients eines Fensters.

/// //////////////////////////////////////////////////////////////////////////

void set_client_size (::HWND hwnd, const size_t& width, const size_t& height)
{
    if (!hwnd || !::IsWindow (hwnd))
        return;

    ::RECT rect_window;
    ::GetWindowRect (hwnd, &rect_window);
   
    ::RECT rect_client;
    ::GetClientRect (hwnd, &rect_client);
   
    ::MoveWindow (hwnd,
                  rect_window.left,
                  rect_window.top,
                  rect_window.right - rect_window.left + (width - rect_client.right),
                  rect_window.bottom - rect_window.top + (height - rect_client.bottom),
                  true);
}

/// //////////////////////////////////////////////////////////////////////////

/// Fensterprozedur.

/// //////////////////////////////////////////////////////////////////////////

::LPARAM WINAPI window_procedure (::HWND hwnd, ::UINT message, ::WPARAM wParam, ::LPARAM lParam)
{
    switch (message)
    {
    HANDLE_MSG (hwnd, WM_CREATE, on_create);
    HANDLE_MSG (hwnd, WM_DESTROY, on_destroy);
    HANDLE_MSG (hwnd, WM_PAINT, on_paint);
    HANDLE_MSG (hwnd, WM_SIZE, on_size);
    }

    return (::DefWindowProc (hwnd, message, wParam, lParam));
}

/// //////////////////////////////////////////////////////////////////////////

/// Implementierung von der Fensternachricht: WM_CREATE

/// //////////////////////////////////////////////////////////////////////////

bool on_create (::HWND hwnd, ::CREATESTRUCT* create_struct)
{
    return (true);
}

/// //////////////////////////////////////////////////////////////////////////

/// Implementierung von der Fensternachricht: WM_DESTROY

/// //////////////////////////////////////////////////////////////////////////

void on_destroy (::HWND hwnd)
{
    ::PostQuitMessage (0);
}

/// //////////////////////////////////////////////////////////////////////////

/// Implementierung von der Fensternachricht: WM_PAINT

/// //////////////////////////////////////////////////////////////////////////

void on_paint (::HWND hwnd)
{
    ::PAINTSTRUCT paint_struct;

    ::BeginPaint (hwnd, &paint_struct);
    ::FillRect (paint_struct.hdc, &paint_struct.rcPaint, static_cast<::HBRUSH>(::GetStockObject (BLACK_BRUSH)));
    ::EndPaint (hwnd, &paint_struct);
}

/// //////////////////////////////////////////////////////////////////////////

/// Implementierung von der Fensternachricht: WM_SIZE

/// //////////////////////////////////////////////////////////////////////////

void on_size (::HWND hwnd, ::UINT state, int width, int height)
{
    set_client_size (hwnd, 800, 600);
}


/// //////////////////////////////////////////////////////////////////////////

/// Programmeinsprungspunkt.

/// //////////////////////////////////////////////////////////////////////////

int WINAPI _tWinMain (::HINSTANCE instance, ::HINSTANCE previous_instance, ::TCHAR* commandline, int show)
{
    ::WNDCLASS window_class;
    ::ZeroMemory (&window_class, sizeof (window_class));

    const ::TCHAR* class_name = _T ("Test Window Class");

    window_class.style          = CS_HREDRAW|CS_VREDRAW;
    window_class.lpfnWndProc    = window_procedure;
    window_class.hInstance      = instance;
    window_class.hIcon          = ::LoadIcon (NULL, IDI_APPLICATION);
    window_class.hCursor        = ::LoadCursor (NULL, IDC_ARROW);
    window_class.hbrBackground  = static_cast<::HBRUSH>(::GetStockObject (BLACK_BRUSH));
    window_class.lpszClassName  = class_name;

    if (!::RegisterClass(&window_class))
        return 0;

    ::HWND hwnd = ::CreateWindow (class_name, 
                                  _T ("TestWindow"),
                                  WS_OVERLAPPEDWINDOW,
                                  CW_USEDEFAULT, CW_USEDEFAULT, 0, 0,
                                  NULL, 
                                  NULL, 
                                  instance, NULL);
    if (!::IsWindow (hwnd))
        return 0;

    ::ShowWindow (hwnd, SW_SHOWNORMAL);
    ::UpdateWindow (hwnd);

    ::MSG message;
    while (::GetMessage(&message, NULL, 0, 0))
    {
        ::TranslateMessage (&message);
        ::DispatchMessage (&message);
    }

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


So wird Software entwickelt!

9

14.04.2009, 12:01

Zitat von »"unsigned long"«

Nein, nicht genehm, denn das was du da machst ist Strunks. Nennen wir das Kind beim Namen.

In den Code den du gepostet hast, fehlte ja selbst die Hauptschleife. Dann meine Frage: Warum hast du dann eine Fensterprozedur, wenn du die Nachrichten nicht verarbeiten kannst mangels fehlender Hauptschleife? Ist doch Nonsens!

Hier ich hab dir mal auf die Schnelle ein Beispiel runtergehauen was optimal ist und dir mal zeigt wie es richtig geht! Mit Struktur und ohne wirren Kram. Allein schon dein Gemische von TCHAR und WCHAR ist mehr als nur gefährlich (ebenso wie falsche Fehlercodes an Windows zurückliefern.)

Aus welchem Grund sollte denn die Hauptschleife in der Adjustfunktion sein? Und wo ist da ein TCHAR und WCHAR Mischmasch? ich kann nirgends auch nur eins von beiden entdecken...
Lieber dumm fragen, als dumm bleiben!

Anonymous

unregistriert

10

14.04.2009, 12:05

Jonathan_Klein
Er hat den Code ja wieder entfernt, weshalb dein Post nun außerhalb des Context ist.

Sind wir mal ehrlich: Hälst du mich wirklich für so knülle das ich die Windows-Nachrichtenverarbeitung in eine SetClientSize-Funktion reinstopfe?!

Werbeanzeige