Toon posts:

[C/Win32] groep buttons in scrollbaar sub-window plaatsen

Pagina: 1
Acties:

Onderwerpen


  • blorf
  • Registratie: December 2003
  • Laatst online: 18-05 03:01
Hallo, ik ben een paar dagen bezig met dit win32-probeersel. Het is een simpel progje dat tekstdata inleest en aan de hand daarvan een lijst met knoppen weergeeft. Het aantal knoppen kan dus varieren van 1 naar heel veel waar mogelijk een scrollbar voor nodig is. Het probleem is dat ik het scrollen niet aan de praat krijg als ik de knoppen in een sub-window plaats.

Kan iemand me i.i.g. een beetje op gang helpen met die scrollbar-windows en messages? Wat ik ervan begrijp is dat je de scrollbar range moet instellen en dmv de WS_VSCROLL of WS_HSCROLL messages de positie bijwerken.

In dit voorbeeld heb ik de buttons, het sub_window waar de buttons in moeten komen en nog een aparte scrollbar allemaal op het main window neergezet. Om de buttons child van sub_window te maken, wat de bedoeling is moet regel 154 ( hwnd ) veranderen in sub_window.


code:
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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
#include <windows.h>
#include <stdio.h>
#include <string.h>

LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
  
char szClassName[ ] = "WindowsApp";

char regel[4096];
char * regel_ptr = regel;

int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nFunsterStil)
{
  HWND hwnd, subtest;            
  MSG messages;        
  WNDCLASSEX wincl;  

  //-------------------------------------------------- bestand lezen
  {
    HANDLE hFile;
    DWORD  dwBytesRead;
    hFile = CreateFile(
      "input.txt",                   
      GENERIC_READ,                 
      0,                           
      NULL,                         
      OPEN_EXISTING,              
      FILE_ATTRIBUTE_NORMAL,     
      NULL
    );
    ReadFile(hFile, regel, 4000, &dwBytesRead , NULL);
  }

  wincl.hInstance = hThisInstance;
  wincl.lpszClassName = szClassName;
  wincl.lpfnWndProc = WindowProcedure;    
  wincl.style = CS_DBLCLKS;                 
  wincl.cbSize = sizeof (WNDCLASSEX);
  wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
  wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
  wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
  wincl.lpszMenuName = NULL;             
  wincl.cbClsExtra = 0;                      
  wincl.cbWndExtra = 0;           
  wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;

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

  hwnd = CreateWindowEx (
         0,                   
         szClassName,         
         "testapp",         
         WS_OVERLAPPEDWINDOW,
         CW_USEDEFAULT,      
         CW_USEDEFAULT,      
         1000,               
         600,                
         HWND_DESKTOP,       
         NULL,               
         hThisInstance,      
         NULL                
  );

  ShowWindow (hwnd, nFunsterStil);

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

  return messages.wParam;
}

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{

  HWND button_array[100],
       test,
       sub_window,
       scrollbar_window;

      char naam[20];           
      int  next_pos=0,
           button_count=0,
           Xcrd=5,
           Ycrd=5;

  switch (message)   
  {
    case WM_DESTROY:
      PostQuitMessage (0);  
      break;
    case WM_CREATE:

      SetScrollRange(sub_window, SB_CTL, 0, 100, TRUE);         // proberen scroll range in te stellen maar werkt niet

      // het sub-window met eigen scrolbars
      sub_window = CreateWindow(
        "static",
        NULL,
        WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL | ES_LEFT | ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL,
        500,
        50,
        300,
        300,
        hwnd,
        0,
        ((LPCREATESTRUCT) lParam)->hInstance,
        NULL
      );

      // de losse scrollbar
      scrollbar_window = CreateWindow(
        "Scrollbar", 
        (LPSTR)NULL,
        WS_CHILD | WS_VISIBLE | SBS_VERT | SBS_RIGHTALIGN,
        900,10,20,400,
        hwnd,
        0,
        ((LPCREATESTRUCT) lParam)->hInstance,
        NULL
      );

      // de exit knop
      test = CreateWindow (
        "button",/* Builtin button class */
        "exit",
        WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
        500,
        400,
        100,
        25,
        hwnd,
        (HMENU) 99,/* Control ID: 2 */
        ((LPCREATESTRUCT) lParam)->hInstance,
        NULL
      );           

      // de bestands data weergeven als knopppen
      while ( strncmp("<einde>", regel_ptr, 7) )
      {
        while ( (int) regel_ptr[next_pos] != 13 ) next_pos++;
        strncpy(naam, regel_ptr, next_pos);
        naam[next_pos]= (int) NULL;
        button_array[button_count] = CreateWindow (
          "button",/* Builtin button class */
          naam,
          WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
          Xcrd,
          Ycrd,
          400,
          30,
          hwnd,
          (HMENU) 1,
          ((LPCREATESTRUCT) lParam)->hInstance,
          NULL
        );           

        next_pos+=2;
        regel_ptr+=next_pos;
        next_pos=0;
        button_count++;
        Ycrd+=35;
      }
      break;
    case WM_COMMAND:
      if (LOWORD(wParam) == 99 && HIWORD(wParam) == BN_CLICKED) 
      {
        DestroyWindow (hwnd);
      }
      return 0;
      break;

      case WM_VSCROLL:
        SetScrollPos((HWND)lParam, SB_CTL, 100, TRUE);     // proberen naar einde te scrollen, maar werkt niet
        break;
       
    default:           
      return DefWindowProc (hwnd, message, wParam, lParam);
  }
  return 0;
}


voorbeeld benodigde databestand input.txt, gemaakt met notepad.exe:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
jan
34
klaas
65
piet
492
karel
45
henk
452
kees
345
<einde>

[Voor 4% gewijzigd door blorf op 26-02-2012 17:46]

You are in a maze of little twisting passages, all different.


  • jmzeeman
  • Registratie: April 2007
  • Laatst online: 01-06 14:55
Heb je Scroll Bar Controls op MSDN al is doorgelezen dat geeft volgens mij een redelijk uitgebreide uitleg.

Acties:
  • 0Henk 'm!

  • blorf
  • Registratie: December 2003
  • Laatst online: 18-05 03:01
jmzeeman schreef op zondag 26 februari 2012 @ 19:21:
Heb je Scroll Bar Controls op MSDN al is doorgelezen dat geeft volgens mij een redelijk uitgebreide uitleg.
Of ik die gelezen heb :F
Duidelijk vind ik het niet, maar dat kan aan mij liggen, ik ben FreeBSD-er en heb nooit iets voor Windows gemaakt behalve ooit wat kleins in Vbscript en Lua. Ze doen het gelijk op twee manieren zonder een duidelijk voorbeeld: een window met eigen scrollbars en een met een externe scrollbar.
Die heb in dit progje dus ook allebei neergezet. Het gaat me er nu om dat een klik op de scrollbar of evt. een scrollwheel beweging een message doorgeeft aan de WindowProcedure functie.
Die moet dus weten van welke scrollbar het bericht komt en wat ermee gedaan moet worden. Daarvoor probeer ik de functies SetScrollRange en SetScrollPos te gebruiken...

[Voor 7% gewijzigd door blorf op 04-03-2012 09:45]

You are in a maze of little twisting passages, all different.


Acties:
  • 0Henk 'm!

  • DataGhost
  • Registratie: Augustus 2003
  • Laatst online: 02-06 16:33

DataGhost

iPL dev

Als je doel niet is de Windows API te leren en het geen harde eis is dat je een kale C-app maakt zou je misschien kunnen kijken naar frameworks zoals bijvoorbeeld Qt. Die hebben al die meuk al een keer voor je uitgezocht en dan kan jij je lekker bezig houden met functionaliteit :)

Acties:
  • 0Henk 'm!

  • blorf
  • Registratie: December 2003
  • Laatst online: 18-05 03:01
Ik snap wat je bedoelt, maar ik wil eigenlijk wel de API leren en juist niet afhankelijk zijn van externe libs. Vanwege mijn werk is het in een aantal gevallen een voordeel dat ik instant kleine win32 tooltjes kan maken. Ik doe het nu via Cygwin met een texteditor, maar daar hangen je programma's verplicht aan cygwin.dll.
Later zal het wel Dev C++ worden, maar ik moet nog een wennen aan zo'n IDE. Doe mij maar een paar xterms met vi oid en manpages van alle C-libs.

You are in a maze of little twisting passages, all different.


  • jmzeeman
  • Registratie: April 2007
  • Laatst online: 01-06 14:55
Wat in ieder geval al fout gaat is dat je op (r96) SetScrollrange aanroept op een uninitailised handle voor het verkeerde window. Als je set scrollrange naar regel 124 verplaatst en op scrollbar_window aanroept zou het al wat beter moeten werken. Verder op krijg je dan in WM_*SCROLL via je wParam de positie waar naar toe gescrolled moet worden en de manier van scrollen door.
Om te weten welke scrollbar je scroll message gestuurd heeft kan je gebruik maken van de lParam hier in staat de window handle van de scrollbar waar de message vandaan komt of NULL als het de eigen scrollbars van een window zijn. Als je deze wilt vergelijken zal je er wel voor moeten zorgen dat je de handles wat langer bewaard als alleen tijdens het createn.
Je zal vervolgens al het scroll werk (voor niet standaard controls) zelf moeten regelen en dus zelf er voor moeten zorgen dat dingen op de goede plaats komen te staan en dat de scroll bar op de goede plek met de goede grootte staat.
Als je de controls in een scrollable panel wilt hebben zal je niet een static control (die volgens mij alleen maar zijn eigen text kan scrollen) maar een eigen window class voor je sub window moeten maken met weer een eigen windowproc die het scrollen en het verplaatsen van zijn child windows regelt.

Scrollen Bijna alles in Win32 is veel werk :)

[Voor 67% gewijzigd door jmzeeman op 06-03-2012 08:04]

Pagina: 1


Tweakers maakt gebruik van cookies

Tweakers plaatst functionele en analytische cookies voor het functioneren van de website en het verbeteren van de website-ervaring. Deze cookies zijn noodzakelijk. Om op Tweakers relevantere advertenties te tonen en om ingesloten content van derden te tonen (bijvoorbeeld video's), vragen we je toestemming. Via ingesloten content kunnen derde partijen diensten leveren en verbeteren, bezoekersstatistieken bijhouden, gepersonaliseerde content tonen, gerichte advertenties tonen en gebruikersprofielen opbouwen. Hiervoor worden apparaatgegevens, IP-adres, geolocatie en surfgedrag vastgelegd.

Meer informatie vind je in ons cookiebeleid.

Sluiten

Toestemming beheren

Hieronder kun je per doeleinde of partij toestemming geven of intrekken. Meer informatie vind je in ons cookiebeleid.

Functioneel en analytisch

Deze cookies zijn noodzakelijk voor het functioneren van de website en het verbeteren van de website-ervaring. Klik op het informatie-icoon voor meer informatie. Meer details

janee

    Relevantere advertenties

    Dit beperkt het aantal keer dat dezelfde advertentie getoond wordt (frequency capping) en maakt het mogelijk om binnen Tweakers contextuele advertenties te tonen op basis van pagina's die je hebt bezocht. Meer details

    Tweakers genereert een willekeurige unieke code als identifier. Deze data wordt niet gedeeld met adverteerders of andere derde partijen en je kunt niet buiten Tweakers gevolgd worden. Indien je bent ingelogd, wordt deze identifier gekoppeld aan je account. Indien je niet bent ingelogd, wordt deze identifier gekoppeld aan je sessie die maximaal 4 maanden actief blijft. Je kunt deze toestemming te allen tijde intrekken.

    Ingesloten content van derden

    Deze cookies kunnen door derde partijen geplaatst worden via ingesloten content. Klik op het informatie-icoon voor meer informatie over de verwerkingsdoeleinden. Meer details

    janee