Форум программистов, компьютерный форум, киберфорум
Delphi
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.64/11: Рейтинг темы: голосов - 11, средняя оценка - 4.64
24 / 24 / 7
Регистрация: 23.03.2013
Сообщений: 140

Загрузка файлов в потоке с отображением прогресса

24.03.2013, 00:11. Показов 2337. Ответов 3
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
У меня есть класс AutoUpdaterKit (Класс со всем необходимым для встраивания системы автообновлений в программы)
Проблема в том, что отображение прогресса подвисает. Думаю, нужно загрузку файлов в поток кинуть. Только вот с потоками я не дружу.

1) Нужно ли вообще кидать загрузку файлов в поток или дело в другом?
2) Если нужно кидать в поток, то как это сделать (хотя-бы намекните))

П.С. Класс немного переписан под конкретную программу, поэтому там встречаются Form, Log.
П.С.2. Класс вообще написан неплохо или совсем коряво?

Заранее спасибо за помощь!

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
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
unit AutoUpdaterKit;
 
interface
 
uses classes, Sysutils, IdBaseComponent, IdComponent, Forms,
  IdTCPConnection, IdTCPClient, IdHTTP, ExtCtrls, ComCtrls;
 
type
  TError = procedure(Sender: TObject; Error: string) of object;
 
type
  TMD5 = array[0..15]of byte;
 
    procedure   md5(s:string; var Hash:TMD5); overload;
    function    md5(s:string):string; overload;
    function    md5_file(sFileName:string; var Hash:TMD5):boolean; overload;
    function    md5_file(sFileName:string):string; overload;
    procedure   ScanDir(StartDir: string; List: TStrings; Log: string; Dir: string='');
    procedure   CheckFromLists(flist1,flist2:TStrings; dlist:TStrings);
    procedure   CheckFromFiles(filename1,filename2:string; dlist:TStrings);
 
type
  TTheDownloader = class(TObject)
    Client: TIdHTTP;
    Size, SizeAll, Ready, Wk: integer;
    Progress: TProgressBar;
    ProgressAll: TProgressBar;
    Url, FileName: string;
  private
    FonError: TError;
    Save: TMemoryStream;
    procedure IdHTTP1WorkBegin(ASender: TObject; AWorkMode: TWorkMode;
      AWorkCountMax: Int64);
    procedure IdHTTP1Work(ASender: TObject; AWorkMode: TWorkMode;
      AWorkCount: Int64);
    procedure IdHTTP1WorkEnd(ASender: TObject; AWorkMode: TWorkMode);
  public
    property onError: TError read FonError write FonError;
    constructor Create;
    destructor Destroy; override;
    procedure Download;
    function GetSize: Integer;
    procedure AutoFileName;
    procedure DownloadFile(link: string);
    procedure DownloadList(list: TStrings; server: string='');
  end;
 
implementation
uses Unit1;
 
var a:TMD5;
 
lenhi, lenlo: longword;
index: cardinal;
hashbuffer: array[0..63] of byte;
currenthash: array[0..3] of cardinal;
 
{ TTheDownloader }
 
constructor TTheDownloader.Create;
begin
  inherited;
  Client := TIdHTTP.Create;
  Save   := TMemoryStream.Create;
  Client.OnWorkBegin := IdHTTP1WorkBegin;
  Client.OnWork := IdHTTP1Work;
  Client.OnWorkEnd := IdHTTP1WorkEnd;
end;
 
destructor TTheDownloader.Destroy;
begin
  Client.Free;
  inherited;
end;
 
procedure TTheDownloader.Download;
begin
  Size := GetSize;
  Save.Clear;
  Client.Get(Url,Save);
end;
 
procedure TTheDownloader.DownloadFile(link: string);
begin
  Url  := link;
  AutoFileName;
  Download;
end;
 
procedure TTheDownloader.DownloadList(list: TStrings; server: string='');
var i,k: integer;
begin
 
  SizeAll := 0;
  Ready := 0;
  i := 1;
  k := list.Count;
 
  repeat
    SizeAll := SizeAll + StrToInt(list[i]);
    i := i + 2;
  until i>(k-1);
 
  i := 0;
 
  repeat
    DownloadFile(server + list.Strings[i]);
    i := i + 2;
  until (i>(k-1)) or (list.Strings[i]='');
 
  Form1.Log('Загрузка завершена!');
  Form1.HashUpdate;
 
end;
 
function TTheDownloader.GetSize: integer;
begin
  Client.Head(Url);
  GetSize := Client.Response.ContentLength;
end;
 
procedure TTheDownloader.IdHTTP1WorkBegin(ASender: TObject; AWorkMode: TWorkMode;
  AWorkCountMax: Int64);
begin
  Progress.Max    := AWorkCountMax;
  ProgressAll.Max := SizeAll;
end;
 
procedure TTheDownloader.IdHTTP1Work(ASender: TObject; AWorkMode: TWorkMode;
  AWorkCount: Int64);
begin
      Progress.Position    := AWorkCount;
      ProgressAll.Position := Ready + AWorkCount;
      Application.ProcessMessages;
end;
 
procedure TTheDownloader.IdHTTP1WorkEnd(ASender: TObject; AWorkMode: TWorkMode);
var fpath: string;
begin
  Progress.Position := Progress.Max;
  Ready := Ready + Progress.Max;
  fpath := exename + ExtractFilePath(FileName);
  if not DirectoryExists(fpath) then ForceDirectories(fpath);
  Save.SaveToFile(FileName);
end;
 
procedure TTheDownloader.AutoFileName;
var i:Word;
begin
  for i:=Length(Url) downto 1 do
    if Url[i]='/' then
    begin
      FileName := copy(Url,i+1,Length(Url));
      exit;
    end;
end;
 
          // -------------------------------------
          // ---------------- MD5 ----------------
          // -------------------------------------
 
{---------------------------------}
procedure burn;
begin
    lenhi:= 0; lenlo:= 0; index:= 0;
    fillchar(hashbuffer,sizeof(hashbuffer),0);
    fillchar(currenthash,sizeof(currenthash),0);
end;
{---------------------------------}
procedure init;
begin
    burn;
    currenthash[0]:= $67452301;
    currenthash[1]:= $efcdab89;
    currenthash[2]:= $98badcfe;
    currenthash[3]:= $10325476;
end;
{---------------------------------}
function lrot32(a, b: longword): longword;
begin
    result:= (a shl b) or (a shr (32-b));
end;
{---------------------------------}
procedure compress;
var
    data: array[0..15] of cardinal;
    a, b, c, d: cardinal;
begin
    move(hashbuffer,data,sizeof(data));
    a:= currenthash[0];
    b:= currenthash[1];
    c:= currenthash[2];
    d:= currenthash[3];
 
    a:= b + lrot32(a + (d xor (b and (c xor d))) + data[ 0] + $d76aa478, 7);
    d:= a + lrot32(d + (c xor (a and (b xor c))) + data[ 1] + $e8c7b756,12);
    c:= d + lrot32(c + (b xor (d and (a xor b))) + data[ 2] + $242070db,17);
    b:= c + lrot32(b + (a xor (c and (d xor a))) + data[ 3] + $c1bdceee,22);
    a:= b + lrot32(a + (d xor (b and (c xor d))) + data[ 4] + $f57c0faf, 7);
    d:= a + lrot32(d + (c xor (a and (b xor c))) + data[ 5] + $4787c62a,12);
    c:= d + lrot32(c + (b xor (d and (a xor b))) + data[ 6] + $a8304613,17);
    b:= c + lrot32(b + (a xor (c and (d xor a))) + data[ 7] + $fd469501,22);
    a:= b + lrot32(a + (d xor (b and (c xor d))) + data[ 8] + $698098d8, 7);
    d:= a + lrot32(d + (c xor (a and (b xor c))) + data[ 9] + $8b44f7af,12);
    c:= d + lrot32(c + (b xor (d and (a xor b))) + data[10] + $ffff5bb1,17);
    b:= c + lrot32(b + (a xor (c and (d xor a))) + data[11] + $895cd7be,22);
    a:= b + lrot32(a + (d xor (b and (c xor d))) + data[12] + $6b901122, 7);
    d:= a + lrot32(d + (c xor (a and (b xor c))) + data[13] + $fd987193,12);
    c:= d + lrot32(c + (b xor (d and (a xor b))) + data[14] + $a679438e,17);
    b:= c + lrot32(b + (a xor (c and (d xor a))) + data[15] + $49b40821,22);
 
    a:= b + lrot32(a + (c xor (d and (b xor c))) + data[ 1] + $f61e2562, 5);
    d:= a + lrot32(d + (b xor (c and (a xor b))) + data[ 6] + $c040b340, 9);
    c:= d + lrot32(c + (a xor (b and (d xor a))) + data[11] + $265e5a51,14);
    b:= c + lrot32(b + (d xor (a and (c xor d))) + data[ 0] + $e9b6c7aa,20);
    a:= b + lrot32(a + (c xor (d and (b xor c))) + data[ 5] + $d62f105d, 5);
    d:= a + lrot32(d + (b xor (c and (a xor b))) + data[10] + $02441453, 9);
    c:= d + lrot32(c + (a xor (b and (d xor a))) + data[15] + $d8a1e681,14);
    b:= c + lrot32(b + (d xor (a and (c xor d))) + data[ 4] + $e7d3fbc8,20);
    a:= b + lrot32(a + (c xor (d and (b xor c))) + data[ 9] + $21e1cde6, 5);
    d:= a + lrot32(d + (b xor (c and (a xor b))) + data[14] + $c33707d6, 9);
    c:= d + lrot32(c + (a xor (b and (d xor a))) + data[ 3] + $f4d50d87,14);
    b:= c + lrot32(b + (d xor (a and (c xor d))) + data[ 8] + $455a14ed,20);
    a:= b + lrot32(a + (c xor (d and (b xor c))) + data[13] + $a9e3e905, 5);
    d:= a + lrot32(d + (b xor (c and (a xor b))) + data[ 2] + $fcefa3f8, 9);
    c:= d + lrot32(c + (a xor (b and (d xor a))) + data[ 7] + $676f02d9,14);
    b:= c + lrot32(b + (d xor (a and (c xor d))) + data[12] + $8d2a4c8a,20);
 
    a:= b + lrot32(a + (b xor c xor d) + data[ 5] + $fffa3942, 4);
    d:= a + lrot32(d + (a xor b xor c) + data[ 8] + $8771f681,11);
    c:= d + lrot32(c + (d xor a xor b) + data[11] + $6d9d6122,16);
    b:= c + lrot32(b + (c xor d xor a) + data[14] + $fde5380c,23);
    a:= b + lrot32(a + (b xor c xor d) + data[ 1] + $a4beea44, 4);
    d:= a + lrot32(d + (a xor b xor c) + data[ 4] + $4bdecfa9,11);
    c:= d + lrot32(c + (d xor a xor b) + data[ 7] + $f6bb4b60,16);
    b:= c + lrot32(b + (c xor d xor a) + data[10] + $bebfbc70,23);
    a:= b + lrot32(a + (b xor c xor d) + data[13] + $289b7ec6, 4);
    d:= a + lrot32(d + (a xor b xor c) + data[ 0] + $eaa127fa,11);
    c:= d + lrot32(c + (d xor a xor b) + data[ 3] + $d4ef3085,16);
    b:= c + lrot32(b + (c xor d xor a) + data[ 6] + $04881d05,23);
    a:= b + lrot32(a + (b xor c xor d) + data[ 9] + $d9d4d039, 4);
    d:= a + lrot32(d + (a xor b xor c) + data[12] + $e6db99e5,11);
    c:= d + lrot32(c + (d xor a xor b) + data[15] + $1fa27cf8,16);
    b:= c + lrot32(b + (c xor d xor a) + data[ 2] + $c4ac5665,23);
 
    a:= b + lrot32(a + (c xor (b or (not d))) + data[ 0] + $f4292244, 6);
    d:= a + lrot32(d + (b xor (a or (not c))) + data[ 7] + $432aff97,10);
    c:= d + lrot32(c + (a xor (d or (not b))) + data[14] + $ab9423a7,15);
    b:= c + lrot32(b + (d xor (c or (not a))) + data[ 5] + $fc93a039,21);
    a:= b + lrot32(a + (c xor (b or (not d))) + data[12] + $655b59c3, 6);
    d:= a + lrot32(d + (b xor (a or (not c))) + data[ 3] + $8f0ccc92,10);
    c:= d + lrot32(c + (a xor (d or (not b))) + data[10] + $ffeff47d,15);
    b:= c + lrot32(b + (d xor (c or (not a))) + data[ 1] + $85845dd1,21);
    a:= b + lrot32(a + (c xor (b or (not d))) + data[ 8] + $6fa87e4f, 6);
    d:= a + lrot32(d + (b xor (a or (not c))) + data[15] + $fe2ce6e0,10);
    c:= d + lrot32(c + (a xor (d or (not b))) + data[ 6] + $a3014314,15);
    b:= c + lrot32(b + (d xor (c or (not a))) + data[13] + $4e0811a1,21);
    a:= b + lrot32(a + (c xor (b or (not d))) + data[ 4] + $f7537e82, 6);
    d:= a + lrot32(d + (b xor (a or (not c))) + data[11] + $bd3af235,10);
    c:= d + lrot32(c + (a xor (d or (not b))) + data[ 2] + $2ad7d2bb,15);
    b:= c + lrot32(b + (d xor (c or (not a))) + data[ 9] + $eb86d391,21);
 
    inc(currenthash[0],a);
    inc(currenthash[1],b);
    inc(currenthash[2],c);
    inc(currenthash[3],d);
    index:= 0;
    fillchar(hashbuffer,sizeof(hashbuffer),0);
end;
{---------------------------------}
procedure update(const buffer; size: longword);
var pbuf: ^byte;
begin
    inc(lenhi,size shr 29); //Int64(lenhi,lenlo) := Int64(size) shl 3;
    inc(lenlo,size shl 3);
    if lenlo<(size shl 3) then inc(lenhi);
    pbuf:= @buffer;
    while size> 0 do begin
        if (size)>=(sizeof(hashbuffer)-index) then begin
            move(pbuf^,hashbuffer[index],sizeof(hashbuffer)-index);
            dec(size,sizeof(hashbuffer)-index);
            inc(pbuf,sizeof(hashbuffer)-index);
            compress;
        end else begin
            move(pbuf^,hashbuffer[index],size);
            inc(index,size);
            size:= 0;
        end;
    end;
end;
{---------------------------------}
 
function update_f(var sFileName:string):boolean;
var f:file;
    size :cardinal;
begin
    result := false;
    AssignFile(f, sFileName);
    FileMode := fmOpenRead;
    Reset(f, 1);
    if IOResult()<>0 then exit;
    size := FileSize(f);
    inc(lenhi,size shr 29); //Int64(lenhi,lenlo) := Int64(size) shl 3;
    inc(lenlo,size shl 3);
    if lenlo<(size shl 3) then inc(lenhi);
    while size>0 do begin
        if (size)>=(sizeof(hashbuffer)-index) then begin
            BlockRead(f,hashbuffer[index],sizeof(hashbuffer)-index);
            dec(size,sizeof(hashbuffer)-index);
            compress;
        end else begin
            BlockRead(f,hashbuffer[index],size);
            inc(index,size);
            size:= 0;
        end;
    end;
    CloseFile(f);
    result := true;
end;
 
{---------------------------------}
procedure final(var digest);
begin
    hashbuffer[index]:= $80;
    if index>= 56 then compress;
    pcardinal(@hashbuffer[56])^:= lenlo;
    pcardinal(@hashbuffer[60])^:= lenhi;
    compress;
    move(currenthash,digest,sizeof(currenthash));
    burn;
end;
{---------------------------------}
 
procedure md5(s:string; var Hash:TMD5);
begin
    init;
    update(s[1],length(s));
    final(a);
    Hash := a;
    burn;
end;
 
function md5(s:string):string;
var i:integer;
    m:TMD5;
begin
    md5(s,m);
    for i:=0 to 15 do
        result:=result+inttohex(m[i],2);
end;
 
function md5_file(sFileName:string; var Hash:TMD5):boolean;
begin
    result:=false;
    init;
    if (sFileName='') or (not update_f(sFileName)) then exit;
    final(a);
    Hash := a;
    burn;
    result := true;
end;
 
function md5_file(sFileName:string):string;
var i:integer;
    m:TMD5;
begin
    if not md5_file(sFileName,m) then
        result := ''
    else
        for i:=0 to 15 do
            result:=result+inttohex(m[i],2);
end;
 
procedure ScanDir(StartDir: string; List: TStrings; Log: string; Dir: string='');
var
  SearchRec: TSearchRec;
  Mask, md5: string;
begin
  Mask := '*.*';
  if StartDir[Length(StartDir)] <> '\' then
    StartDir := StartDir + '\';
  if FindFirst(StartDir + Dir + Mask, faAnyFile, SearchRec) = 0 then
  begin
    repeat
      Application.ProcessMessages;
      if ((SearchRec.Attr and faDirectory) <> faDirectory)
      then
      begin
        md5 := '';
        md5 := md5_file(StartDir + Dir + SearchRec.Name);
        List.Add(Dir + SearchRec.Name);
        List.Add(md5);
        List.Add(IntToStr(SearchRec.Size));
      end
      else if (SearchRec.Name <> '..') and (SearchRec.Name <> '.') then
      begin
        ScanDir(StartDir, List, Log, Dir + SearchRec.Name + '\');
      end;
    until FindNext(SearchRec) <> 0;
    FindClose(SearchRec);
    List.SaveToFile(Log);
  end;
end;
 
procedure CheckFromLists(flist1,flist2:TStrings; dlist:TStrings);
var i,k,f:integer;
begin
 
  k := flist1.Count;
  i := 0;
 
  repeat
 
    f := flist2.IndexOf(flist1.Strings[i]);
 
    if flist1.Strings[i+1] <> flist2.Strings[f+1] then
    begin
      dlist.Add(flist1.Strings[i]);
      dlist.Add(flist1.Strings[i+2]);
    end;
 
    i := i + 3;
 
  until (i>(k-1)) or (flist1.Strings[i]='');
 
end;
 
procedure CheckFromFiles(filename1,filename2:string; dlist:TStrings);
var fserver,flocal: TStringList;
begin
 
  fserver := TStringList.Create;
  fserver.LoadFromFile(filename1);
  flocal := TStringList.Create;
  flocal.LoadFromFile(filename2);
  CheckFromLists(fserver,flocal,dlist);
 
end;
 
end.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
24.03.2013, 00:11
Ответы с готовыми решениями:

Загрузка файла с FTP с отображением прогресса
Всем привет. Задача: Есть форма. На ней два элемента - прогресс бар и кнопка. При нажатии на кнопку, должна начаться закачка файла...

Загрузка файла на ftp с отображением прогресса
Всемм доброго времени суток форумчане с наступающим вас 2013 годом всего счастливого!!!! И вот мой вопрос: Мне нужна программа которая...

Скачивание файлов с отображением прогресса
Как это реализовать? И присоединить к процессу скачки прогрессбар?

3
 Аватар для Rurr
23 / 23 / 11
Регистрация: 12.01.2013
Сообщений: 223
24.03.2013, 00:34
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
type
MyPotok = class (TThread)
private
protected procedure execute; override;
public
......
 
procedure MyPotok.execute;
begin
//код который должен выполнятся в потоке
end;
 
procedure Form1.Button1Click(Sender:TObject);
var tok: MyPotok;
begin
tok.Create(false);
tok.FreeOnTerminate;
end;
1
24 / 24 / 7
Регистрация: 23.03.2013
Сообщений: 140
25.03.2013, 00:06  [ТС]
Основы работы с потоками я знаю, но как конкретно в этом случае поступить? Тут нет основного кода, который нужно было бы поместить в execute.

Добавлено через 22 часа 23 минуты
Проблема решена.
0
24 / 24 / 7
Регистрация: 23.03.2013
Сообщений: 140
25.03.2013, 00:11  [ТС]
У меня есть класс AutoUpdaterKit (Класс со всем необходимым для встраивания системы автообновлений в программы)
Проблема в том, что отображение прогресса подвисает. Думаю, нужно загрузку файлов в поток кинуть. Только вот с потоками я не дружу.

1) Нужно ли вообще кидать загрузку файлов в поток или дело в другом?
2) Если нужно кидать в поток, то как это сделать (хотя-бы намекните))

Заранее спасибо за помощь!

Добавлено через 4 часа 58 минут
Проблема решена.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
25.03.2013, 00:11
Помогаю со студенческими работами здесь

Закачка файлов из интернета с отображением прогресса закачивания
My.Computer.Network.DownloadFile(&quot;http://cdimage.debian.org/debian-cd/6.0.3/multi-arch/iso-cd/debian-6.0.3-amd64-i386-netinst.iso&quot;,...

Асинхронное скачивание нескольких файлов с отображением прогресса
Уже несколько вечеров не могу устроить себе &quot;поочередное скачивание от 1 до 4 файлов с отображением прогресса&quot;, пробовал реализвоать...

Загрузка файлов через WebClient с отображением процентов
Здравствуйте, не очень понимаю, как сделать вывод процентов загрузки. Хочу сделать ProgressBar на консоли(сам прогрессбар есть). Можно...

Копирование файла с отображением прогресса
Всем добрый вечер.Помогите пожалуйста реализовать такую задачу.Условно, есть две папки в одной из них лежит файл и надо его скопировать и...

Метод с отображением прогресса для BackgroundWorker
Здравствуйте! Пишу статический класс и в нем есть метод, который долго прорабатывается. Как сделать, чтоб этот метод мог вызывать событие...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Новые блоги и статьи
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru