Subversion Repositories Kolibri OS

Rev

Rev 4413 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4413 leency 1
#include "..\lib\list_box.h"
4411 leency 2
 
4413 leency 3
 
4411 leency 4
int	downloader_id;
5
 
6
dword
7
	buf,
8
	filesize,
9
	blink;
10
 
11
char download_path[]="/rd/1/.download";
12
char search_path[]="http://nigma.ru/index.php?s=";
13
 
4414 leency 14
struct lines{
15
	int visible, all, first, column_max;
16
};
4411 leency 17
 
18
struct TWebBrowser {
4413 leency 19
	llist list;
4411 leency 20
	void GetNewUrl();
21
	void OpenPage();
22
	void ReadHtml(byte);
23
	void ShowPage();
24
	void ParseHTML(dword);
25
	void WhatTextStyle(int left1, top1, width1);
26
	void DrawPage();
27
	void DrawScroller();
28
};
29
TWebBrowser WB1;
30
 
31
byte rez, b_text, i_text, u_text, s_text, pre_text, blq_text, li_text,
32
	link, ignor_text, li_tab, cur_encoding, text_align;
33
 
34
enum { ALIGN_LEFT, ALIGN_CENTER, ALIGN_RIGHT};
35
 
36
dword text_colors[300],
37
	text_color_index,
38
	link_color,
39
	bg_color;
40
 
41
int stroka,
42
	stolbec,
43
	tab_len,
44
	anchor_line_num;
45
 
46
char line[500],
47
	tag[100],
48
	tagparam[10000],
49
	parametr[1200],
50
	options[4096],
51
	anchor[256];
52
 
53
#include "..\TWB\colors.h"
54
#include "..\TWB\unicode_tags.h"
55
#include "..\TWB\img_cache.h"
56
#include "..\TWB\some_code.h"
57
#include "..\TWB\parce_tag.h"
58
#include "..\TWB\draw_buf.h"
59
 
60
//=======================================================================
61
 
62
 
63
void TWebBrowser::DrawPage()
64
{
65
	int start_x, start_y, line_length, magrin_left=5;
66
 
67
	if (!header)
68
	{
69
		strcpy(#header, #line);
70
		strcat(#header, " -");
71
		strcat(#header, #version);
72
		line = 0;
73
		return;
74
	}
75
 
76
	if (stroka >= 0) && (stroka - 2 < lines.visible) && (line) && (!anchor)
77
	{
4414 leency 78
		start_x = stolbec * 6 + list.x + magrin_left;
79
		start_y = stroka * 10 + list.y + magrin_left;
4411 leency 80
		line_length = strlen(#line) * 6;
81
 
82
		WriteBufText(start_x, 0, 0x88, text_colors[text_color_index], #line, drawbuf);
83
		IF (b_text)	WriteBufText(start_x+1, 0, 0x88, text_colors[text_color_index], #line, drawbuf);
4414 leency 84
		IF (i_text) DrawBufSkew(start_x, 0, line_length, list.line_h);
4411 leency 85
		IF (s_text) DrawBufBar(start_x, 4, line_length, 1, text_colors[text_color_index]);
86
		IF (u_text) DrawBufBar(start_x, 8, line_length, 1, text_colors[text_color_index]);
87
		IF (link) {
88
			UnsafeDefineButton(start_x-2, start_y, line_length + 3, 9, blink + BT_HIDE, 0xB5BFC9);
89
			DrawBufBar(start_x, 8, line_length, 1, text_colors[text_color_index]);
90
		}
91
		stolbec += strlen(#line);
92
	}
93
}
94
//=======================================================================
95
 
96
 
97
 
98
char *ABSOLUTE_LINKS[]={ "http:", "mailto:", "ftp:", "/sys/", "/kolibrios/", "/rd/", "/bd", "/hd", "/cd", "/tmp", "/usbhd", 0};
99
//dword TWebBrowser::GetNewUrl(dword CUR_URL, NEW_URL){
100
void TWebBrowser::GetNewUrl(){
101
	int i, len;
102
 
103
	for (i=0; ABSOLUTE_LINKS[i]; i++)
104
	{
105
		len=strlen(ABSOLUTE_LINKS[i]);
106
		if (!strcmpn(#URL, ABSOLUTE_LINKS[i], len)) return;
107
	}
108
 
109
	IF (!strcmpn(#URL,"./", 2)) strcpy(#URL, #URL+2); //игнорим :)
110
	strcpy(#editURL, BrowserHistory.CurrentUrl()); //достаём адрес текущей страницы
111
 
112
	if (URL[0] == '/')
113
	{
114
		i = strchr(#editURL+8, '/');
115
		editURL[i+7]=0;
116
		strcpy(#URL, #URL+1);
117
	}
118
 
119
	_CUT_ST_LEVEL_MARK:
120
 
121
		if (editURL[strrchr(#editURL, '/')-2]<>'/')  // если не http://
122
		{
123
			editURL[strrchr(#editURL, '/')] = 0x00; //обрезаем её урл до последнего /
124
		}
125
 
126
		IF (!strcmp(get_URL_part(3),"../")) //на уровень вверх
127
		{
128
			strcpy(#URL,#URL+3);
129
			editURL[strrchr(#editURL, '/')-1] = 0x00; //обрезаем её урл до последнего /
130
			goto _CUT_ST_LEVEL_MARK;
131
		}
132
 
133
		if (editURL[strlen(#editURL)-1]<>'/') strcat(#editURL, "/");
134
 
135
		strcat(#editURL, #URL); //клеим новый адрес
136
		strcpy(#URL, #editURL);
137
}
138
 
139
 
140
 
141
void TWebBrowser::ReadHtml(byte encoding)
142
{
143
	if (!strcmp(get_URL_part(5),"http:")))
144
		file_size stdcall (#download_path);
145
	else
146
		file_size stdcall (#URL);
147
 
148
	filesize = EBX;
149
	if (!filesize) return;
150
 
151
	mem_Free(buf);
152
	buf = mem_Alloc(filesize);
153
	if (!strcmp(get_URL_part(5),"http:")))
154
		ReadFile(0, filesize, buf, #download_path);
155
	else
156
		ReadFile(0, filesize, buf, #URL);
157
 
158
	cur_encoding = encoding;
159
	if (encoding==_WIN) wintodos(buf);
160
	if (encoding==_UTF) utf8rutodos(buf);
161
	if (encoding==_KOI) koitodos(buf);
162
}
163
 
164
 
165
void TWebBrowser::OpenPage()
166
{
167
	if (GetProcessSlot(downloader_id)<>0) PutPaletteImage(#toolbar,200,42,0,0,8,#toolbar_pal);
168
	KillProcess(downloader_id);
169
	strcpy(#editURL, #URL);
170
	BrowserHistory.AddUrl();
171
	strcpy(#header, #version);
172
	pre_text =0;
173
	if (!strcmp(get_URL_part(5),"http:")))
174
	{
175
		KillProcess(downloader_id); //убиваем старый процесс
176
		DeleteFile(#download_path);
177
		IF (URL[strlen(#URL)-1]=='/') URL[strlen(#URL)-1]=NULL;
178
		downloader_id = RunProgram("/sys/network/downloader", #URL);
179
		//Browser Hack v2.0
180
		/*
181
		pause(60);
182
		if (GetProcessSlot(downloader_id)<>0)
183
		{
184
			debug("Browser Hack v2.0: Killing downloader and trying to run it one more!");
185
			KillProcess(downloader_id); //убиваем старый процесс
186
			downloader_id = RunProgram("/sys/network/downloader", #URL);
187
		}
188
		*/
189
		IF (downloader_id<0) RunProgram("@notify", "Error running Downloader. Internet unavilable.");
190
		Draw_Window();
191
		return;
192
	}
193
	lines.first = lines.all =0;
194
	ReadHtml(_WIN);
195
	WB1.ShowPage();
196
}
197
 
198
 
199
void TWebBrowser::ShowPage()
200
{
201
	address_box.size = address_box.pos = strlen(#editURL);
202
	address_box.offset=0;
203
	edit_box_draw stdcall(#address_box);
204
 
205
	if (!filesize)
206
	{
4414 leency 207
		DrawBar(list.x, list.y, list.w+scroll1.size_x+1, list.h, 0xFFFFFF); //fill all
208
		if (GetProcessSlot(downloader_id)<>0) WriteText(list.x + 10, list.y + 18, 0x80, 0, "Loading...");
4411 leency 209
		else
210
		{
4414 leency 211
			WriteText(list.x + 10, list.y + 18, 0x80, 0, "Page not found. May be, URL contains some errors.");
212
			if (!strcmp(get_URL_part(5),"http:"))) WriteText(list.x + 10, list.y + 32, 0x80, 0, "Or Internet unavilable for your configuration.");
4411 leency 213
		}
214
		//return;
215
	}
216
	else
217
		ParseHTML(buf);
218
 
219
	if (!header) strcpy(#header, #version);
220
	if (!strcmp(#version, #header)) DrawTitle(#header);
221
}
222
 
223
 
224
 
225
void TWebBrowser::ParseHTML(dword bword){
226
	word bukva[2];
227
	int j, perenos_num;
228
	byte ignor_param;
229
	char temp[768];
230
 
231
	if (blink<400) blink=400; else for ( ; blink>400; blink--;) DeleteButton(blink);
232
	b_text = i_text = u_text = s_text = blq_text =
233
	li_text = link = ignor_text = text_color_index = text_colors[0] = li_tab = 0; //обнуляем теги
234
	text_align = ALIGN_LEFT;
235
	link_color = 0x0000FF;
236
	bg_color = 0xFFFFFF;
237
	DrawBufFill();
238
	strcpy(#page_links,"|");
239
	strcpy(#header, #version);
240
	stroka = -lines.first;
241
	stolbec = 0;
242
	line = 0;
243
 
244
	if (pre_text<>2)
245
	{
246
		pre_text=0;
247
		if (!strcmp(#URL + strlen(#URL) - 4, ".txt")) pre_text = 1;
248
		if (!strcmp(#URL + strlen(#URL) - 4, ".mht")) ignor_text = 1;
249
	}
250
 
251
	for ( ; buf+filesize > bword; bword++;)
252
	{
253
		bukva = ESBYTE[bword];
254
		if (ignor_text) && (bukva<>'<') continue;
255
		switch (bukva)
256
		{
257
		case 0x0a:
258
			if (pre_text)
259
			{
260
				bukva = temp = NULL;
261
				goto NEXT_MARK;
262
			}
263
		case '\9':
264
			if (pre_text) //иначе идём на 0x0d
265
			{
266
				tab_len=strlen(#line)/8;
267
				tab_len=tab_len*8;
268
				tab_len=8+tab_len-strlen(#line);
269
				for (j=0; j
270
				break;
271
			}
272
			goto DEFAULT_MARK;
273
		case '=': //quoted printable
274
			if (strcmp(#URL + strlen(#URL) - 4, ".mht")<>0) goto DEFAULT_MARK;
275
 
276
			temp[0] = ESBYTE[bword+1];
277
			temp[1] = ESBYTE[bword+2];
278
			temp[2] = '\0';
279
			if (bukva = Hex2Symb(#temp))
280
			{
281
				bword+=2;
282
				goto DEFAULT_MARK;
283
			}
284
			break;
285
 
286
		case '&': //  and so on
287
			bword++;
288
			tag=0;
289
			for (j=0; (ESBYTE[bword]<>';') && (j<7);   j++, bword++;)
290
			{
291
				bukva = ESBYTE[bword];
292
				chrcat(#tag, bukva);
293
			}
294
			bukva = GetUnicodeSymbol();
295
			if (bukva) goto DEFAULT_MARK;
296
			break;
297
		case '<':
298
			bword++; //промотаем символ <
299
			tag = parametr = tagparam = ignor_param = NULL;
300
			if (ESBYTE[bword] == '!') //фильтрация внутри , дерзко
301
			{
302
				bword++;
303
				if (ESBYTE[bword] == '-')
304
				{
305
				HH_:
306
					do
307
					{
308
						bword++;
309
						if (buf + filesize <= bword) break 2;
310
					}
311
					while (ESBYTE[bword] <>'-');
312
 
313
					bword++;
314
					if (ESBYTE[bword] <>'-') goto HH_;
315
				}
316
			}
317
			while (ESBYTE[bword] !='>') && (bword < buf + filesize) //получаем тег и его параметры
318
			{
319
				bukva = ESBYTE[bword];
320
				if (bukva == '\9') || (bukva == '\x0a') || (bukva == '\x0d') bukva = ' ';
321
				if (!ignor_param) && (bukva <>' ')
322
				{
323
					if (strlen(#tag)
324
				}
325
				else
326
				{
327
					ignor_param = true;
328
					if (!ignor_text) && (strlen(#tagparam)+1
329
				}
330
				bword++;
331
			}
332
			strlwr(#tag);
333
			strlwr(#tagparam);
334
 
335
			if (tag[strlen(#tag)-1]=='/') tag[strlen(#tag)-1]=NULL; //for br/
336
			if (tagparam) && (strlen(#tagparam) < 4000) GetNextParam();
337
 
338
			if (stolbec + strlen(#line) > lines.column_max) //============the same as NEXT_MARK
339
			{
340
				perenos_num = strrchr(#line, ' ');
341
				if (!perenos_num) && (strlen(#line)>lines.column_max) perenos_num=lines.column_max;
342
				strcpy(#temp, #line + perenos_num); //перенос по словам
343
				line[perenos_num] = 0x00;
344
				if (stroka-1 > lines.visible) && (lines.first <>0) break 1; //уходим...
345
				DrawPage();
346
				strcpy(#line, #temp);
4414 leency 347
				TextGoDown(list.x + 5, stroka * 10 + list.y + 5, list.w - 20); //закрашиваем следущую строку
4411 leency 348
			}
349
			DrawPage();
350
			line=NULL;
351
 
4414 leency 352
			if (tag) WhatTextStyle(list.x + 5, stroka * 10 + list.y + 5, list.w - 20); //обработка тегов
4411 leency 353
 
354
			tag = parametr = tagparam = ignor_param = NULL;
355
			break;
356
		default:
357
			DEFAULT_MARK:
358
			if (bukva<=15) bukva=' ';
359
			if (!pre_text) && (bukva == ' ')
360
			{
361
				if (line[strlen(#line)-1]==' ') break; //убрать 2 пробела подряд
362
				if (!stolbec) && (!line) break; //строка не может начинаться с пробела
363
			}
364
			if (strlen(#line)
365
 
366
			if (stolbec + strlen(#line) > lines.column_max)
367
			{
368
			NEXT_MARK:
369
				perenos_num = strrchr(#line, ' ');
370
				if (!perenos_num) && (strlen(#line)>lines.column_max) perenos_num=lines.column_max;
371
				strcpy(#temp, #line + perenos_num); //перенос по словам
372
				line[perenos_num] = 0x00;
373
				if (stroka-1 > lines.visible) && (lines.first <>0) break 1; //уходим...
374
				DrawPage();
375
				strcpy(#line, #temp);
4414 leency 376
				TextGoDown(list.x + 5, stroka * 10 + list.y + 5, list.w - 20); //закрашиваем следущую строку
4411 leency 377
			}
378
		}
379
	}
380
 
381
	DrawPage(); //рисует последнюю строку, потом это надо убрать, оптимизировав код
4414 leency 382
	TextGoDown(list.x + 5, stroka * 10 + list.y + 5, list.w - 20); //закрашиваем следущую строку
4411 leency 383
 
4414 leency 384
	if (lines.visible * 10 + 25 <= list.h)
385
		DrawBar(list.x, lines.visible * 10 + list.y + 25, list.w, -lines.visible * 10 + list.h - 25, bg_color);
386
	if (stroka * 10 + 5 <= list.h)
387
		DrawBar(list.x, stroka * 10 + list.y + 5, list.w, -stroka * 10 + list.h - 5, bg_color); //закрашиваем всё до конца
4411 leency 388
	if (lines.first == 0) lines.all = stroka;
389
	if (anchor) //если посреди текста появится новый якорь - будет бесконечный цикл
390
	{
391
		anchor=NULL;
392
		lines.first=anchor_line_num;
393
		ParseHTML(buf);
394
	}
395
	DrawScroller();
396
}
397
 
398
 
399
 
400
char oldtag[100];
401
void TWebBrowser::WhatTextStyle(int left1, top1, width1) {
402
	dword hr_color;
403
 
404
	//проверяем тег открывается или закрывается
405
	if (tag[0] == '/')
406
	{
407
		 rez = 0;
408
		 strcpy(#tag, #tag+1);
409
	}
410
	else rez = 1;
411
 
412
	if (!chTag("html"))
413
	{
414
		IF(!strcmp(#URL + strlen(#URL) - 4, ".mht")) IF (rez==0) ignor_text = 1; ELSE ignor_text = 0;
415
		return;
416
	}
417
 
418
	if (!chTag("script")) || (!chTag("style")) || (!chTag("binary")) ignor_text = rez;
419
 
420
	if(!chTag("title"))
421
	{
422
		if (rez) header=NULL;
423
		else if (!stroka) DrawTitle(#header); //тег закрылся - вывели строку
424
		return;
425
	}
426
 
427
	if (ignor_text) return;
428
 
429
 
430
 
431
	IF(!chTag("q")) chrcat(#line, '\"');
432
 
433
	if (anchor) && (!strcmp(#parametr, "id=")) //очень плохо!!! потому что если не последний тег, работать не будет
434
	{
435
		if (!strcmp(#anchor, #options))	anchor_line_num=lines.first+stroka;
436
	}
437
 
438
	if (!chTag("body"))
439
	{
440
		do{
441
			if (!strcmp(#parametr, "link=")) link_color = GetColor(#options);
442
			if (!strcmp(#parametr, "text=")) text_colors[0]=GetColor(#options);
443
			if (!strcmp(#parametr, "bgcolor="))
444
			{
445
				bg_color=GetColor(#options);
446
				DrawBufFill();
447
			}
448
		} while(GetNextParam());
449
		return;
450
	}
451
 
452
	if (!chTag("a"))
453
	{
454
		if (rez)
455
		{
456
			if (link) IF(text_color_index > 0) text_color_index--; //если предыдущий тег а не был закрыт
457
 
458
			do{
459
				if (!strcmp(#parametr, "href="))
460
				{
461
					if (stroka - 1 > lines.visible) || (stroka < -2) return;
462
 
463
					text_color_index++;
464
					text_colors[text_color_index] = text_colors[text_color_index-1];
465
 
466
					link = 1;
467
					blink++;
468
					text_colors[text_color_index] = link_color;
469
					strcat(#page_links, #options);
470
					strcat(#page_links, "|");
471
				}
472
				if (anchor) && (!strcmp(#parametr, "name="))
473
				{
474
					if (!strcmp(#anchor, #options))
475
					{
476
						anchor_line_num=lines.first+stroka;
477
					}
478
				}
479
			} while(GetNextParam());
480
		}
481
		else {
482
			link = 0;
483
			IF(text_color_index > 0) text_color_index--;
484
		}
485
		return;
486
	}
487
 
488
	if (!chTag("font"))
489
	{
490
		if (rez)
491
		{
492
			text_color_index++;
493
			text_colors[text_color_index] = text_colors[text_color_index-1];
494
 
495
			do{
496
				if (strcmp(#parametr, "color=") == 0) //&& (parametr[1] == '#')
497
				{
498
					text_colors[text_color_index] = GetColor(#options);
499
				}
500
			} while(GetNextParam());
501
		}
502
		else
503
			if (text_color_index > 0) text_color_index--;
504
		return;
505
	}
506
	if(!chTag("tr")) || (!chTag("br")) {
507
		TextGoDown(left1, top1, width1);
508
		return;
509
	}
510
	if (!chTag("div")) {
511
		IF(oldtag[0] <>'h') TextGoDown(left1, top1, width1);
512
		return;
513
	}
514
	if (!chTag("p")) {
515
		IF(oldtag[0] == 'h') return;
516
		TextGoDown(left1, top1, width1);
517
		IF(rez) TextGoDown(left1, top1 + 10, width1);
518
		return;
519
	}
520
	if (!chTag("center"))
521
	{
522
		if (rez) text_align = ALIGN_CENTER;
523
		if (!rez)
524
		{
525
			TextGoDown(left1, top1, width1);
526
			text_align = ALIGN_LEFT;
527
		}
528
		return;
529
	}
530
	if (!chTag("right"))
531
	{
532
		if (rez) text_align = ALIGN_RIGHT;
533
		if (!rez)
534
		{
535
			TextGoDown(left1, top1, width1);
536
			text_align = ALIGN_LEFT;
537
		}
538
		return;
539
	}
540
	if (!chTag("h1")) || (!chTag("h2")) || (!chTag("h3")) || (!chTag("h4")) {
541
		TextGoDown(left1, top1, width1);
542
		if (rez) && (stroka>1) TextGoDown(left1, top1 + 10, width1);
543
		strcpy(#oldtag, #tag);
544
		if (rez)
545
		{
546
			if (!strcmp(#parametr, "align=")) && (!strcmp(#options,"center")) text_align = ALIGN_CENTER;
547
			if (!strcmp(#parametr, "align=")) && (!strcmp(#options,"right")) text_align = ALIGN_RIGHT;
548
			b_text = 1;
549
		}
550
		if (!rez)
551
		{
552
			text_align = ALIGN_LEFT;
553
			b_text = 0;
554
		}
555
		return;
556
	}
557
	else
558
		oldtag=NULL;
559
 
560
	if (!chTag("b")) || (!chTag("strong")) || (!chTag("big")) {
561
		b_text = rez;
562
		return;
563
	}
564
	if(!chTag("i")) || (!chTag("em")) || (!chTag("subtitle")) {
565
		i_text = rez;
566
		return;
567
	}
568
	if (!chTag("dt"))
569
	{
570
		li_text = rez;
571
		IF(rez == 0) return;
572
		TextGoDown(left1, top1, width1);
573
		return;
574
	}
575
	if(!chTag("li")) || (!chTag("dt")) //надо сделать вложенные списки
576
	{
577
		li_text = rez;
578
		if (rez)
579
		{
580
			TextGoDown(left1, top1, width1);
4414 leency 581
			if (stroka > -1) && (stroka - 2 < lines.visible) DrawBufBar(li_tab * 5 * 6 + left1 - 5, list.line_h/2-3, 2, 2, 0x555555);
4411 leency 582
		}
583
		return;
584
	}
585
	if (!chTag("u")) || (!chTag("ins")) u_text = rez;
586
	if (!chTag("s")) || (!chTag("strike")) || (!chTag("del")) s_text = rez;
587
	if (!chTag("ul")) || (!chTag("ol")) IF(!rez)
588
	{
589
		li_text = rez;
590
		li_tab--;
591
		TextGoDown(left1, top1, width1);
592
	} ELSE li_tab++;
593
	if (!chTag("dd")) stolbec += 5;
594
	if (!chTag("blockquote")) blq_text = rez;
595
	if (!chTag("pre")) pre_text = rez;
596
	if (!chTag("hr"))
597
	{
598
		if (anchor) || (stroka < -1)
599
		{
600
			stroka+=2;
601
			return;
602
		}
603
		if (strcmp(#parametr, "color=") == 0) hr_color = GetColor(#options); else hr_color = 0x999999;
604
		TextGoDown(left1, top1, width1);
4414 leency 605
		DrawBufBar(5, WB1.list.line_h/2, WB1.list.w-10, 1, hr_color);
606
		TextGoDown(left1, top1+WB1.list.line_h, width1);
4411 leency 607
	}
608
	if (!chTag("img"))
609
	{
610
		Images( left1, top1, width1);
611
		return;
612
	}
613
	if (!chTag("meta")) || (!chTag("?xml"))
614
	{
615
		do{
616
			if (!strcmp(#parametr, "charset=")) || (!strcmp(#parametr, "content=")) || (!strcmp(#parametr, "encoding="))
617
			{
618
				strcpy(#options, #options[strrchr(#options, '=')]); //поиск в content=
619
				if (!strcmp(#options,"utf-8"))   || (!strcmp(#options,"utf8"))      ReadHtml(_UTF);
620
				if (!strcmp(#options, "koi8-r")) || (!strcmp(#options, "koi8-u"))   ReadHtml(_KOI);
621
				if (!strcmp(#options, "dos"))    || (!strcmp(#options, "cp-866"))   ReadHtml(_DOS);
622
			}
623
		} while(GetNextParam());
624
		return;
625
	}
626
}
627
 
628
 
629
 
630
void TWebBrowser::DrawScroller() //не оптимальная отрисовка, но зато в одном месте
631
{
632
	scroll1.max_area = lines.all;
633
	scroll1.cur_area = lines.visible;
634
	scroll1.position = lines.first;
635
 
636
	scroll1.all_redraw=1;
4414 leency 637
	scroll1.start_x = WB1.list.x + WB1.list.w;
638
	scroll1.size_y=WB1.list.h;
4411 leency 639
 
640
	scrollbar_v_draw(#scroll1);
641
}
642