Avatar billede Slettet bruger
11. juni 2003 - 19:56 Der er 8 kommentarer og
1 løsning

Windowsprogrammerings spørgsmål

Jeg roder lidt med noget windowsprogrammering. Jeg anvender bogen "Programming Windows" som er skrevet af Charles Petzold.

Men i kapitel 4 er jeg stødt ind i et forståelses problem, og det lyder som følger:

Først laves der en vilved navn "sysmets.h" som ser ud som følger:
#define NUMLINES ((int) (sizeof sysmetrics / sizeof sysmetrics [0]))

struct
{
    int    iIndex ;
    TCHAR * szLabel ;
    TCHAR * szDesc ;
}
sysmetrics [] =
{
    SM_CXSCREEN,            TEXT ("SM_CXSCREEN"),             
                              TEXT ("Screen width in pixels"),
    SM_CYSCREEN,            TEXT ("SM_CYSCREEN"),             
                              TEXT ("Screen height in pixels"),
    SM_CXVSCROLL,            TEXT ("SM_CXVSCROLL"),           
                              TEXT ("Vertical scroll width"),
    SM_CYHSCROLL,            TEXT ("SM_CYHSCROLL"),           
                              TEXT ("Horizontal scroll height"),
    SM_CYCAPTION,            TEXT ("SM_CYCAPTION"),           
                              TEXT ("Caption bar height"),
.......
}

Derefter bliver der lavet en fil "sysmets1.c" og som ser ud som følger:

#define WINVER 0x0500
#include <windows.h>
#include "sysmets.h"

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    PSTR szCmdLine, int iCmdShow)
{
    static TCHAR szAppName[] = TEXT ("SysMets1") ;
    HWND        hwnd ;
    MSG          msg ;
    WNDCLASS    wndclass ;

    wndclass.style        = CS_HREDRAW | CS_VREDRAW ;
    wndclass.lpfnWndProc  = WndProc ;
    wndclass.cbClsExtra    = 0 ;
    wndclass.cbWndExtra    = 0 ;
    wndclass.hInstance    = hInstance ;
    wndclass.hIcon        = LoadIcon (NULL, IDI_APPLICATION) ;
    wndclass.hCursor      = LoadCursor (NULL, IDC_ARROW) ;
    wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
    wndclass.lpszMenuName  = NULL ;
    wndclass.lpszClassName = szAppName ;

    if (!RegisterClass (&wndclass))
    {
          MessageBox (NULL, TEXT ("This program requires Windows NT!"),
                      szAppName, MB_ICONERROR) ;
          return 0 ;
    }

    hwnd = CreateWindow (szAppName, TEXT ("Get System Metrics No. 1"),
                          WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, NULL, hInstance, NULL) ;

    ShowWindow (hwnd, iCmdShow) ;
    UpdateWindow (hwnd) ;

    while (GetMessage (&msg, NULL, 0, 0))
    {
          TranslateMessage (&msg) ;
          DispatchMessage (&msg) ;
    }
    return msg.wParam ;
}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    static int  cxChar, cxCaps, cyChar ;
    HDC        hdc ;
    int        i ;
    PAINTSTRUCT ps ;
    TCHAR      szBuffer [10] ;
    TEXTMETRIC  tm ;

    switch (message)
    {
    case WM_CREATE:
          hdc = GetDC (hwnd) ;

          GetTextMetrics (hdc, &tm) ;
          cxChar = tm.tmAveCharWidth ;
          cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) * cxChar / 2 ;
          cyChar = tm.tmHeight + tm.tmExternalLeading ;

          ReleaseDC (hwnd, hdc) ;
          return 0 ;

    case WM_PAINT :
          hdc = BeginPaint (hwnd, &ps) ;

          for (i = 0 ; i < NUMLINES ; i++)
          {
              TextOut (hdc, 0, cyChar * i,                     
                        sysmetrics[i].szLabel,
                        lstrlen (sysmetrics[i].szLabel)) ;

              TextOut (hdc, 22 * cxCaps, cyChar * i,     
                        sysmetrics[i].szDesc,
                        lstrlen (sysmetrics[i].szDesc)) ;

              SetTextAlign (hdc, TA_RIGHT | TA_TOP) ;

              TextOut (hdc, 22 * cxCaps + 40 * cxChar, cyChar * i, szBuffer,
                        wsprintf (szBuffer, TEXT ("%5d"),
                            GetSystemMetrics (sysmetrics[i].iIndex))) ;

              SetTextAlign (hdc, TA_LEFT | TA_TOP) ;
          }
          EndPaint (hwnd, &ps) ;
          return 0 ;

    case WM_DESTROY :
          PostQuitMessage (0) ;
          return 0 ;
    }
    return DefWindowProc (hwnd, message, wParam, lParam) ;
}


Mit spørgsmål er så, hvordan virker:
TextOut (hdc, 0, cyChar * i,                     
                        sysmetrics[i].szLabel,
                        lstrlen (sysmetrics[i].szLabel)) ;

Det jeg ikke helt forstår er sysmetrics[i].szLabel som henviser til anden række i .h filen men hvordan??
Avatar billede arne_v Ekspert
11. juni 2003 - 20:04 #1
struct
{
    int    iIndex ;
    TCHAR * szLabel ;
    TCHAR * szDesc ;
}

=> anonym struct med 1 int og 2 strings

sysmetrics []

=> variabel som er et array med det antal elementer der opremses af den anonyme struct

{
    SM_CXSCREEN,            TEXT ("SM_CXSCREEN"),           
                              TEXT ("Screen width in pixels"),
    SM_CYSCREEN,            TEXT ("SM_CYSCREEN"),           
                              TEXT ("Screen height in pixels"),

=> de første 2 elementer i arrayet (hver består af 1 int + 2 strenge)
Avatar billede arne_v Ekspert
11. juni 2003 - 20:04 #2
Og nej - jeg synes heller ikke at det er specielt kønt.
Avatar billede Slettet bruger
11. juni 2003 - 23:36 #3
arne_v> Kan du kort opremse hvad et struct er, som sagt er jeg lidt glemsom for tiden *s*
Avatar billede arne_v Ekspert
12. juni 2003 - 07:35 #4
En struct er en C feature for en "klump" data bestående af
flere felter.

I det her tilfælde består structen af 1 int plus 2 pointerere til
char.

Man kan også bruge struct i C++ men i 99% af tilfældene er ern class
nok bedre beskrivende for hvad man vil.

Fordelene ved at samle sine data i structs fremfor at have
enkelte variable er:
  - man kan returnere en struct fra en funktion
  - man kan assigne en hel struct i et enkelt assignement
  etc.

Det er god C at bruge struct.

Det er kun erklæringen/initialiseringen ovenfor hvor jeg synes at
de starmmer den.
Avatar billede Slettet bruger
12. juni 2003 - 21:05 #5
arne_v> Det jeg ikke helt forstår er hvordan ved sysmetrics[i].szLabel at det drejer sig on kolone 2?? (se herunder)

    case WM_PAINT :
          hdc = BeginPaint (hwnd, &ps) ;

          for (i = 0 ; i < NUMLINES ; i++)
          {
              TextOut (hdc, 0, cyChar * i,                     
                        sysmetrics[i].szLabel,
                        lstrlen (sysmetrics[i].szLabel)) ;

Syntes ikke jeg kan se det er defineret på nogen måde, med mindre at struct definere det ved:
struct
{
    int    iIndex ;
    TCHAR * szLabel ;
    TCHAR * szDesc ;

Så den ved at klumpen af data er samlet som.:
iIndex    szLabel    szDesc
Data1,    Data2,      Data3,
Data4,    Data5,      Data6,
Osv.....
Avatar billede arne_v Ekspert
12. juni 2003 - 21:12 #6
Du har et array af structs - struct består af 3 felter.

Ved initialisering:

data 1 -> første element første felt
data 2 -> første element andet felt
data 3 -> første element tredie felt
data 4 -> andet element første felt
data 5 -> andet element andet felt
data 6 -> andet element tredie felt
Avatar billede Slettet bruger
12. juni 2003 - 21:34 #7
Felterne bliver de så navngivet atomatisk at "Struct"?

I rækkefølgen de bliver initaliseret

    int    iIndex ;
    TCHAR * szLabel ;
    TCHAR * szDesc ;
??
Avatar billede arne_v Ekspert
12. juni 2003 - 21:55 #8
struct'en definerer rækkefølgen af felterne.

Initialiseringen skovler så data ind i samme rækkefølge.
Avatar billede Slettet bruger
12. juni 2003 - 22:00 #9
Smart...

og tak for hjælpen/svarene ;)
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