Форум программистов, компьютерный форум, киберфорум
The trick
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  

Круговой визуализатор спектра

Запись от The trick размещена 27.03.2014 в 03:30
Показов 5828 Комментарии 1
Метки vb

http://youtu.be/h9qteZBkwww

Представляю исходный код и скомпилированную программу графического визуализатора звукового спектра. Звук анализируется через стандартное устройство записи Windows, т.е. можно выбрать микрофон и просматривать спектр с него, либо выбрать стереомикшер и просматривать спектр воспроизводимого звука. В данном визуализаторе имеется возможность регулировки количества отображаемых октав, регулировка прозрачности фона, усиления. Также имеется возможность загрузки палитры из внешних файлов формата PNG в формате 32ARGB, эффекты затухания "размытие" и "горение". Данный визуализатор позволяет просматривать спектр в двух режимах, в виде дуг (колец) и в виде секторов. В первом виде радиальная координата отвечает за частоту по октавам, угловая - между октавами. Гармоники отстоящие от друг друга на октавы, находятся по одну линию, цвет - интенсивность. Во втором режиме, радиальная координата - уровень громкости, цвет - частота, угловая координата - частота (период - 1 октава). Данную идею мне предложил Владислав Петровкий Хакер (http://bbs.vbstreets.ru/member... le&u=8077&), только в его задумке немного по другому должен был отображаться спектр в виде кривой, я сделал в виде секторов.
Модуль modMain:
Visual Basic
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
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
Option Explicit
 
' Ìîäóëü modMain.bas ãëàâíûé ìîäóëü ïðîãðàììû TrickSpectrum
' © Êðèâîóñ Àíàòîëèé Àíàòîëüåâè÷ (The trick), 2014
 
Private Type View                                    ' Òèï îòîáðàæåíèÿ
    fa As Single                                     ' Íà÷àëüíûé óãîë
    ta As Single                                     ' Øèðèíà óãëà
    IsLine As Boolean                                ' ßâëÿåòñÿ ëèíèåé
End Type
 
Public Type Complex                                  ' Êîìïëåêñíîå ÷èñëî
    r As Single
    i As Single
End Type
 
Private mFFTSize As Long                             ' Ðàçìåð FFT
Private mFFTLog  As Long                             ' Log2(FFTSize)
Private mOctaveCount As Long                         ' Êîëè÷åñòâî îêòàâ
Private mSymmetrical As Boolean                      ' Ñèììåòðè÷íîå îòîáðàæåíèå
Private mFade As Single                              ' Êîýôôèöèåíò óãàñàíèÿ
Private mTransparency As Single                      ' Ïðîçðà÷íîñòü
Private mEffect As Long                              ' Ýôôåêò
Private mGain As Long                                ' Óñèëåíèå
Private mTransparent As Boolean                      ' Ïðîçðà÷íîå îêíî
Private mView As Long                                ' Ðåæèì îòîáðàæåíèÿ
 
Dim MapData() As View                                ' Õðàíåíèå îòîáðàæåíèÿ ñîîòâåòñòâèÿ ÷àñòîòû ê êîîðäèíàòå
Dim Spectrum() As Complex                            ' Ðåçóëüòàò FFT ïðåîáðàçîâàíèÿ
Dim Window() As Single                               ' Îêîííàÿ ôóíêöèÿ Õåììèíãà
Dim Palette() As Long                                ' Ïàëèòðà
Dim imgSpectrum As Long                              ' Êàðòèíêà ñïåêòðà
Dim imgSpectrumData() As Long                        ' Ïèêñåëè êàðòèíêè ñïåêòðà
 
Dim grWindow As Long                                 ' Graphics îêíà
Dim grSpectrum As Long                               ' Graphics áóôåðà
Dim Brush As Long                                    ' Êèñòü äëÿ çàëèâêè êðóãà è ñåêòîðîâ
Dim Pen As Long                                      ' Ïåðî äëÿ îòðèñîâêè äóã è ëèíèé
Dim OctAreaSize As Single                            ' Ðàçìåð îáëàñòè îäíîé îêòàâû â ïèêñåëÿõ
Dim Coef(13) As Complex                              ' Êîýôôèöèåíòû äëÿ FFT
Dim FFTInit As Boolean                               ' Èíèöèàëèçèðîâàíû ëè êîýôèöèåíòû äëÿ FFT
Dim ExternalPalette As Boolean                       ' Çàãðóæåíà âíåøíÿÿ ïàëèòðà
 
' Ñâîéñòâî çàäàåò ðàçìåð FFT
Public Property Let FFTSize(ByVal lNewValue As Long)
    Dim lg As Single
    ' Ïðîâåðêà êðàòíî ëè ñòåïåíè 2
    lg = Log(lNewValue) / 0.693147180559945
    If lg <> Fix(lg) Then Exit Property
    ' Ïðîâåðêà âûõîäà çà ïðåäåëû
    If lg > mOctaveCount Or lg < 8 Then Exit Property
    mFFTSize = lNewValue
    mFFTLog = lg
    ' Îáíîâëåíèå ðàçìåðîâ áóôåðîâ
    UpdateBuffers
    ' Îáíîâëåíèå êîîðäèíàò îòîáðàæåíèÿ
    CreateMap
End Property
Public Property Get FFTSize() As Long
    FFTSize = mFFTSize
End Property
 
' Ñâîéñòâî çàäàåò êîëè÷åñòâî îòîáðàæàåìûõ îêòàâ
Public Property Let OctaveCount(ByVal lNewValue As Long)
    ' Ïðîâåðêà âûõîäà çà ãðàíèöû
    If lNewValue > mFFTLog Or lNewValue < 2 Then Exit Property
    ' Ñáðîñ ôëàæêà ñ ïðåäûäóùåé ïîçèöèè â ìåíþ
    CheckMenuItem mnuOct, mOctaveCount - 2, MF_BYPOSITION Or MF_UNCHECKED
    mOctaveCount = lNewValue
    ' Óñòàíîâêà ôëàæêà íà íîâîå ìåñòî â ìåíþ
    CheckMenuItem mnuOct, mOctaveCount - 2, MF_BYPOSITION Or MF_CHECKED
    ' Îáíîâëåíèå êîîðäèíàò îòîáðàæåíèå
    CreateMap
End Property
Public Property Get OctaveCount() As Long
    OctaveCount = mOctaveCount
End Property
 
' Ñâîéñòâî çàäàåò ñãëàæèâàíèå (àíòèàëèàñèíã)
Public Property Let Smoothing(ByVal bNewValue As Boolean)
    GdipSetSmoothingMode grSpectrum, IIf(bNewValue, SmoothingModeAntiAlias, SmoothingModeHighSpeed)
    ' Óñòàíîâêà ôëàæêà â ìåíþ
    CheckMenuItem mnuMain, 1, IIf(bNewValue, MF_CHECKED, MF_UNCHECKED)
End Property
Public Property Get Smoothing() As Boolean
    Dim l As Long
    GdipGetSmoothingMode grSpectrum, l
    Smoothing = l = SmoothingModeAntiAlias
End Property
 
' Ñâîéñòâî çàäàåò îòîáðàæåíèå ñèììåòðè÷íî ïî ãîðèçîíòàëè
Public Property Let Symmetrical(ByVal bNewValue As Boolean)
    mSymmetrical = bNewValue
    ' Óñòàíîâêà ôëàæêà
    CheckMenuItem mnuMain, 0, IIf(bNewValue, MF_CHECKED, MF_UNCHECKED)
    ' Ñîçäàíèå îòîáðàæåíèÿ
    CreateMap
    ' Ñîçäàíèå áóôåðíîé êàðòèíêè
    CreateSpectrumBitmap
End Property
Public Property Get Symmetrical() As Boolean
    Symmetrical = mSymmetrical
End Property
 
' Ñâîéñòâî çàäàåò âêëþ÷åíà ëè ïðîçðà÷íîñòü îêíà
Public Property Let Transparent(ByVal bNewValue As Boolean)
    Dim hRgn As Long
    mTransparent = bNewValue
    ' Óñòàíîâêà ôëàæêà â ìåíþ
    CheckMenuItem mnuMain, 2, IIf(bNewValue, MF_CHECKED, MF_UNCHECKED)
    If mTransparent Then
        ' Åñëè ïðîçðà÷íî
        ' Ñáðîñ ðåãèîíà îêíà
        SetWindowRgn frmMain.hwnd, 0, True
        ' Óñòàíàâëèâàåì ñëîåíûé ñòèëü îêíà
        SetWindowLong frmMain.hwnd, GWL_EXSTYLE, GetWindowLong(frmMain.hwnd, GWL_EXSTYLE) Or WS_EX_LAYERED
    Else
        ' Åñëè íåïðîçðà÷íî
        ' Ñáðàñûâàåì áèò ñëîåíîñòè îêíà
        SetWindowLong frmMain.hwnd, GWL_EXSTYLE, GetWindowLong(frmMain.hwnd, GWL_EXSTYLE) And (Not WS_EX_LAYERED)
        ' Ñîçäàåì êðóãëûé ðåãèîí
        hRgn = CreateEllipticRgn(0, 0, frmMain.ScaleWidth, frmMain.ScaleWidth)
        ' Óñòàíàâëèâàåì åãî â îêíî
        SetWindowRgn frmMain.hwnd, hRgn, True
    End If
End Property
Public Property Get Transparent() As Boolean
    Transparent = mTransparent
End Property
 
' Ñâîéñòâî çàäàåò ýôôåêò àíèìàöèè ôîíà
Public Property Let Effect(ByVal lNewValue As Long)
    ' Ñáðîñ ôëàæêà ñ ïðåäûäóùåé ïîçèöèè â ìåíþ
    CheckMenuItem mnuEffects, mEffect, MF_BYPOSITION Or MF_UNCHECKED
    mEffect = lNewValue
    ' Óñòàíîâêà ôëàæêà íà íîâîå ìåñòî â ìåíþ
    CheckMenuItem mnuEffects, mEffect, MF_BYPOSITION Or MF_CHECKED
End Property
Public Property Get Effect() As Long
    Effect = mEffect
End Property
 
' Ñâîéñòâî çàäàåò ïàðàìåòð çàòóõàíèÿ ôîíà
Public Property Let Fade(ByVal fNewValue As Single)
    ' Ñáðîñ ôëàæêà ñ ïðåäûäóùåé ïîçèöèè â ìåíþ
    CheckMenuItem mnuFade, Sqr(mFade * 100) - 1, MF_BYPOSITION Or MF_UNCHECKED
    mFade = fNewValue
    ' Óñòàíîâêà ôëàæêà íà íîâîå ìåñòî â ìåíþ
    CheckMenuItem mnuFade, Sqr(mFade * 100) - 1, MF_BYPOSITION Or MF_CHECKED
End Property
Public Property Get Fade() As Single
    Fade = mFade
End Property
 
' Ñâîéñòâî çàäàåò ïàðàìåòð óñèëåíèÿ ñèãíàëà ïðè âûâîäå
Public Property Let Gain(ByVal fNewValue As Single)
    ' Ñáðîñ ôëàæêà ñ ïðåäûäóùåé ïîçèöèè â ìåíþ
    CheckMenuItem mnuGain, mGain - 1, MF_BYPOSITION Or MF_UNCHECKED
    mGain = fNewValue
    ' Óñòàíîâêà ôëàæêà íà íîâîå ìåñòî â ìåíþ
    CheckMenuItem mnuGain, mGain - 1, MF_BYPOSITION Or MF_CHECKED
End Property
Public Property Get Gain() As Single
    Gain = mGain
End Property
 
' Ñâîéñòâî çàäàåò ïðîçðà÷íîñòü ïîäëîæêè îêíà
Public Property Let Transparency(ByVal fNewValue As Single)
    ' Ñáðîñ ôëàæêà ñ ïðåäûäóùåé ïîçèöèè â ìåíþ
    CheckMenuItem mnuTransparency, mTransparency * 10 - 1, MF_BYPOSITION Or MF_UNCHECKED
    mTransparency = fNewValue
    ' Óñòàíîâêà ôëàæêà íà íîâîå ìåñòî â ìåíþ
    CheckMenuItem mnuTransparency, mTransparency * 10 - 1, MF_BYPOSITION Or MF_CHECKED
End Property
Public Property Get Transparency() As Single
    Transparency = mTransparency
End Property
 
' Ñâîéñòâî çàäàåò ðåæèì îòîáðàæåíèÿ
Public Property Let View(ByVal lNewValue As Long)
    ' Ñáðîñ ôëàæêà ñ ïðåäûäóùåé ïîçèöèè â ìåíþ
    CheckMenuItem mnuView, mView, MF_BYPOSITION Or MF_UNCHECKED
    mView = lNewValue
    CheckMenuItem mnuView, mView, MF_BYPOSITION Or MF_CHECKED
    ' Óñòàíîâêà ôëàæêà íà íîâîå ìåñòî â ìåíþ
    If mView = 1 Then
        ' Åñëè ðåæèì îòîáðàæåíèÿ â âèäå ñåêòîðîâ
        ' òî çàäàåì øèðèíó ïåðà â 1 ïèêñåëü, äëÿ îòîáðàæåíèÿ òîíêèõ ñåòîðîâ
        GdipSetPenWidth Pen, 1
        ' Ñîçäàåì ïàëèòðó áåç ïðîçðà÷íîñòè
        CreateDefaultSectorPalette
        ' Èíà÷å ñîçäàåì ïàëèòðó ñ ïðîçðà÷íîñòüþ
    Else: CreateDefaultRingPalette
    End If
    ' Ñîçäàåì îòîáðàæåíèå
    CreateMap
End Property
Public Property Get View() As Long
    View = mView
End Property
 
' Ôóíêöèÿ çàãðóæàåò ïàëèòðó èç ôàéëà
Public Function LoadPalette(FileName As String) As Boolean
    Dim bmp As Long, pix As Long, w As Long, x As Long, i As Long, d As Single
    ' Çàãðóæàåì êàðòèíêó
    If GdipLoadImageFromFile(StrPtr(FileName), bmp) Then
        MsgBox "Error opening image"
        Exit Function
    End If
    ' Ïðîâåðÿåì ôîðìàò ïèêñåëåé
    GdipGetImagePixelFormat bmp, pix
    ' Ïîäõîäÿò òîëüêî 32ARGB
    If pix <> PixelFormat32bppARGB Then
        MsgBox "Unsupported pixel format"
        GdipDisposeImage bmp
        Exit Function
    End If
    ' Ïðîâåðÿåì øèðèíó íå ìåíåå 255
    GdipGetImageWidth bmp, w
    If w < 256 Then
        MsgBox "Very small the bitmap. Mininum width - 256 pixels"
        GdipDisposeImage bmp
        Exit Function
    End If
    d = w / 256
    ' Çàäàåì çíà÷åíèÿ ïàëèòðû â ñîîòâåòñòâèè ñ ïèêñåëÿìè ðèñóíêà
    For i = 0 To 255
        x = i * d
        GdipBitmapGetPixel bmp, x, 0, Palette(i)
    Next
    
    ExternalPalette = True
    
    GdipDisposeImage bmp
End Function
' /////////////////////////////////////////////////////Ñòàðòîâàÿ ïðîöåäóðà/////////////////////////////////////////////////////////
Public Sub Main()
    ' Çàãðóæàåì ôîðìó
    Load frmMain
    
    ' Çàäàåì ïàðàìåòðû ïî óìîë÷àíèþ
    mFFTSize = 2048: mFFTLog = 11: mOctaveCount = 7: mFade = 0.81
    mTransparency = 0.5: mSymmetrical = False: mGain = 4
    Transparent = False
    ' Îáíîâëÿåì ðàçìåðû áóôåðîâ
    UpdateBuffers
    ' Ñîçäàåì îòîáðàæåíèå
    CreateMap
    
    ' Èíèöèàëèçèðóåì GDI+
    If Not InitGDIPlus Then Unload frmMain: Exit Sub
    
    ' Ñîçäàåì êèñòü è ïåðî
    If GdipCreateSolidFill(0, Brush) Then MsgBox "Error creating fill": Unload frmMain: Exit Sub
    If GdipCreatePen1(0, 1, UnitPixel, Pen) Then MsgBox "Error creating pen": Unload frmMain: Exit Sub
    
    ' Ïðèðàâíèâàåì øèðèíó è âûñîòó ôîðìû
    frmMain.Height = frmMain.Width
    
    ' Ñîçäàåì ïàëèòðó
    CreateDefaultRingPalette
    ' Ñîçäàåì ìåíþ
    CreateMenu
    ' Ñàáêëàññèì ôîðìó
    Hook
    
    ' Óñòàíîâêà èçíà÷àëüíûõ ôëàæêîâ â ìåíþ
    CheckMenuItem mnuOct, mOctaveCount - 2, MF_BYPOSITION Or MF_CHECKED
    CheckMenuItem mnuTransparency, mTransparency * 10 - 1, MF_BYPOSITION Or MF_CHECKED
    CheckMenuItem mnuFade, Sqr(mFade * 100) - 1, MF_BYPOSITION Or MF_CHECKED
    CheckMenuItem mnuEffects, mEffect, MF_BYPOSITION Or MF_CHECKED
    CheckMenuItem mnuGain, mGain - 1, MF_BYPOSITION Or MF_CHECKED
    CheckMenuItem mnuView, 0, MF_BYPOSITION Or MF_CHECKED
    
    ' Çàõâàòûâàåì çâóê
    If Not InitCapture Then Unload frmMain: Exit Sub
    
    ' Ïîêàçûâàåì ôîðìó
    frmMain.Show
End Sub
 
' Âûõîä èç ïðîãðàììû
Public Sub Quit()
    ' Óäàëÿåì ðåñóðñû GDI+
    If grWindow Then GdipDeleteGraphics grWindow
    If imgSpectrum Then GdipDisposeImage imgSpectrum: GdipDeleteGraphics grSpectrum
    If Pen Then GdipDeletePen Pen
    If Brush Then GdipDeleteBrush Brush
    ' Äåèíèöèàëèçàöèÿ GDI+
    UninitGDIPlus
    ' Óíè÷òîæåíèå ìåíþ
    DeleteMenu
    ' Ñíèìàåì ñàáêëàññèíã
    Unhook
    ' Çàâåðøàåì çàõâàò çâóêà
    EndCapture
End Sub
 
' Ïðè èçìåíåíèè ðàçìåðîâ ôîðìû
Public Sub OnResize()
    ' Åñëè áûë ñîçäàí Graphics îêíà, óäàëÿåì åãî
    If grWindow Then GdipDeleteGraphics grWindow: grWindow = 0
    
    ' Ñîçäàåì íîâûé Graphics ïî ðàçìåðó îêíà
    If GdipCreateFromHDC(frmMain.hdc, grWindow) Then
        MsgBox "Error create GDI+ graphics"
        Unload frmMain: Exit Sub
    End If
    
    ' Äëÿ íåãî âêëþ÷àåì ñãëàæèâàíèå
    GdipSetSmoothingMode grWindow, SmoothingModeAntiAlias
    ' Ñîçäàåì áóôôåðíóþ êàðòèíêó è Graphics
    If Not CreateSpectrumBitmap Then Exit Sub
    ' Ñîçäàåì îòîáðàæåíèå
    CreateMap
End Sub
 
' Ïðîöåäóðà îòðèñîâêè
Public Sub Draw(Wav() As Integer)
    Dim i1 As Long, i2 As Long, c As Long, sz As Currency, pts As Currency, o As Long, _
        Sh As Single, Sw As Single, q1 As Single, q2 As Single, b As Long, fl As Boolean, _
        m As Long, x As Single, y As Single, a As Single, ci As Long
    
    ' Ïåðåâîäèì öåëûå ñòåðåî-âûáîðêè â êîìïëåêñíûé ìîíî-ôîðìàò
    ToComplex Wav(), Spectrum()
    ' Ïðîèçâîäèì áûñòðîå ÏÔ
    FFT Spectrum()
    
    ' Åñëè ðåæèì ñèììåòðè÷íîãî îòîáðàæåíèå, òî
    If mSymmetrical Then
        ' ãîðèçîíòàëüíûé ñäâèã ðàâåí 0
        Sw = 0
    Else
        ' èíà÷å ïîëîâèíå ôîðìû
        Sw = (frmMain.ScaleWidth - 1) / 2
    End If
    ' Âåðòèêàëüíûé ñäâèã = ïîëîâèíå ôîðìû
    Sh = (frmMain.ScaleWidth - 1) / 2
    
    ' Î÷èùàåì îêíî
    GdipGraphicsClear grWindow, ARGB(255, 0)
    ' Óñòàíàâëèâàåì ïðîçðà÷íîñòü ïîäëîæêè
    GdipSetSolidFillColor Brush, ARGB(Transparency * 255, 0)
    ' Çàëèâàåì ïîäëîæêó
    GdipFillEllipse grWindow, Brush, 0, 0, frmMain.ScaleWidth - 1, frmMain.ScaleHeight - 1
 
    ' Àíèìèðóåì ôîí
    Release
    
    ' Ïåðâàÿ ÷àñòîòà
    i1 = 1
    
    ' Â çàâèñèìîñòè îò ðåæèìà îòîáðàæåíèÿ
    Select Case View
    Case 0
        ' Ïðîõîä ïî îêòàâàì
        For o = 0 To mOctaveCount - 1
            ' Ôëàã ïåðåõîäà
            fl = True
            ' Óâåëè÷èâàåì ðàäèóñ íà ðàçìåð îêòàâû
            q2 = q2 + OctAreaSize
            ' Íàõîäèì èíäåêñ ñëåäóþùåé îêòàâû
            i2 = i1 * 2
            ' Ïîõîä ïî èíäåêñàì ñïåêòðà
            Do While i1 < i2
                ' Íàõîäèì àìïëèòóäó ñïåêòðà
                b = Sqr(Spectrum(i1).r * Spectrum(i1).r + Spectrum(i1).i * Spectrum(i1).i)
                ' Îãðàíè÷èâàåì
                If b > 255 Then b = 255
                ' Óñòàíàâëèâàåì öâåò ïåðà â çàâèñèìîñòè îò èíòåíñèâíîñòè àìïëèòóäû
                GdipSetPenColor Pen, Palette(b)
                ' Åñëè îòîáðàæåíèå ÷åðåç ëèíèè
                If MapData(i1).IsLine Then
                    ' Åñëè ïåðåõîäíûé ôëàã, òî óñòàíàâëèâàåì òîëùèíó ïåðà 1 ïèêñåëü
                    If Not fl Then GdipSetPenWidth Pen, 1: fl = True: q1 = q1 + 4: q2 = q2 + 2
                    ' Ðèñóåì ëèíèþ
                    GdipDrawLine grSpectrum, Pen, MapData(i1).fa * q1 + Sw, MapData(i1).ta * q1 + Sh, _
                                                  MapData(i1).fa * q2 + Sw, MapData(i1).ta * q2 + Sh
                Else
                    ' Åñëè ïåðåõîäíûé ôëàã, òî óñòàíàâëèâàåì òîëùèíó ïåðà ðàçìåðó îêòàâû - øèðèíà ðàìêè
                    If fl Then GdipSetPenWidth Pen, OctAreaSize - 2: fl = False
                    ' Ðèñóåì äóãó
                    GdipDrawArc grSpectrum, Pen, Sw - q2, Sh - q2, q2 * 2 - 1, q2 * 2 - 1, MapData(i1).fa, MapData(i1).ta
                End If
                ' Ñëåäóþùèé ñïåêòð
                i1 = i1 + 1
            Loop
            ' Óâåëè÷èâàåì ðàäèóñ, íà ðàçìåð îêòàâû
            q1 = q1 + OctAreaSize
        Next
    Case 1
        ' Êîýôôèöèåíò óñèëåíèÿ
        q1 = (mGain * Gain + 9)
        ' Êîýôôèöèåíò èíäåêñà
        q2 = 255 / ((2 ^ (mOctaveCount + 1)) \ 2)
        ' Ïðîõîä ïî îêòàâàì
        For o = 0 To mOctaveCount - 1
            ' Íàõîäèì èíäåêñ ñëåäóþùåé îêòàâû
            i2 = i1 * 2
            ' Ïîõîä ïî èíäåêñàì ñïåêòðà
            Do While i1 < i2
                ' Íàõîäèì àìïëèòóäó ñïåêòðà è óñèëèâàåì åå
                b = (Log(Sqr(Spectrum(i1).r * Spectrum(i1).r + Spectrum(i1).i * Spectrum(i1).i) _
                    + 0.0001) + 9.21034037197618) * q1
                ' Îãðàíè÷èâàåì
                If b > Sh - 1 Then b = Sh - 1
                ' Åñëè áîëüøå 1 ïèêñåëÿ îòðèñîâûâàåì
                If b > 1 Then
                    ' Íàõîäèì èíäåêñ â ïàëèòðå öâåòà
                    ci = i1 * q2
                    ' Åñëè øèðèíà ñåêòîðà < 2 ïèêñåëåé, òî ðèñóåì ëèíèþ
                    If 6.28318530717959 * b * (MapData(i1).ta / 360) < 2 Then
                        ' Íàõîäèì óãîë â ðàäèàíàõ
                        a = MapData(i1).fa * 1.74532925199433E-02
                        ' Íàõîäèì êîîðäèíàòû êîíöà ëèíèè
                        x = Cos(a) * b + Sw: y = Sin(a) * b + Sh
                        ' Óñòàíàâëèâàåì öâåò ïåðà â çàâèñèìîñòè îò ÷àñòîòû
                        GdipSetPenColor Pen, Palette(ci)
                        ' Ðèñóåì ëèíèþ
                        GdipDrawLine grSpectrum, Pen, Sw, Sh, x, y
                    Else
                        ' Óñòàíàâëèâàåì öâåò çàëèâêè â çàâèñèìîñòè îò ÷àñòîòû
                        GdipSetSolidFillColor Brush, Palette(ci)
                        ' Çàëèâàåì ñåêòîð
                        GdipFillPie grSpectrum, Brush, Sw - b, Sh - b, b * 2, b * 2, MapData(i1).fa, MapData(i1).ta
                    End If
                End If
                ' Ñëåäóþùèé ñïåêòð
                i1 = i1 + 1
            Loop
        Next
    End Select
    
    ' Äëÿ áûñòðîé îòðèñîâêè èç áóôåðà îòêëþ÷àåì ñãëàæèâàíèå
    GdipSetSmoothingMode grWindow, SmoothingModeHighSpeed
    
    ' Äëÿ ñèììåòðè÷íîãî îòîáðàæåíèÿ
    If mSymmetrical Then
        ' îòðèñîâûâàåì äâà çåðêàëüíî-ðàñïîëîæåííûõ áóôåðà
        GdipDrawImageRectI grWindow, imgSpectrum, Sh, 0, -Sh, Sh * 2 + 1
        GdipDrawImageI grWindow, imgSpectrum, Sh, 0
    Else
        ' èíà÷å ðèñóåì êàê åñòü
        GdipDrawImageI grWindow, imgSpectrum, 0, 0
    End If
    
    ' Óñòàíàâëèâàåì ñãëàæèâàíèå äëÿ îêíà
    GdipSetSmoothingMode grWindow, SmoothingModeAntiAlias
    
    ' Îòðèñîâûâàåì èç áóôôåðíîãî DC íà ñåáÿ
    frmMain.Refresh
    ' Èíèöèàëèçàöèÿ ïåðåìåííîé ðàçìåðà
    sz = (frmMain.ScaleWidth + CCur(frmMain.ScaleHeight) * 4294967296#) / 10000
    
    ' Åñëè îêíî ñëîåíîå, òî îáíîâëÿåì åãî ñîñòîÿíèå
    If mTransparent Then
        UpdateLayeredWindow frmMain.hwnd, frmMain.hdc, ByVal 0, sz, frmMain.hdc, pts, 0, AB_32Bpp255, ULW_ALPHA
    End If
End Sub
 
' Ôóíêöèÿ ñîçäàåò áóôôåðíóþ êàðòèíêó è áóôôåðíûé Graphics
Private Function CreateSpectrumBitmap() As Boolean
    Dim s As Boolean, w As Long
    
    ' Çàïîìèíàåì ðåæèì ñãëàæèâàíèÿ
    s = Smoothing
    ' Óäàëÿåì ïðè íåîáõîäèìîñòè ðåñóðû GDI+
    If imgSpectrum Then GdipDisposeImage imgSpectrum: GdipDeleteGraphics grSpectrum
    ' Îïðåäåëÿåì øèðèíó áóôåðíîé êàðòèíêè
    w = IIf(mSymmetrical, frmMain.ScaleWidth / 2, frmMain.ScaleWidth)
    ' Âûäåëÿåì ìåñòî ïîä áèòû ðèñóíêà
    ReDim imgSpectrumData(w - 1, frmMain.ScaleHeight - 1)
    ' Ñîçäàåì ðèñóíîê
    If GdipCreateBitmapFromScan0(w, frmMain.ScaleHeight, w * 4, PixelFormat32bppARGB, imgSpectrumData(0, 0), imgSpectrum) Then
        MsgBox "Error create GDI+ bitmap"
        Unload frmMain: Exit Function
    End If
    ' Ñîçäàåì Graphics
    If GdipGetImageGraphicsContext(imgSpectrum, grSpectrum) Then
        MsgBox "Error create buffer graphics"
        Unload frmMain: Exit Function
    End If
    ' Óñòàíàâëèâàåì íà ìåñòî ðåæèì ñãëàæèâàíèÿ
    Smoothing = s
    ' Óäà÷íî
    CreateSpectrumBitmap = True
End Function
 
' Ïðîöåäóðà àíèìèðóåò ôîí
Private Sub Release()
    Dim x As Long, y As Long, c As Long, d As Long, w As Long, h As Long
    Dim r As Long, g As Long, b As Long, a As Long, dx As Long, dy As Long
    Dim cx As Single, cy As Single, Buf() As Long, o As Single, s As Single
    
    ' Îïðåäåëÿåì øèðèíó è âûñîòó ðèñóíêà - 1
    h = UBound(imgSpectrumData, 2): w = UBound(imgSpectrumData, 1)
    
    ' Â çàâèñèìîñòè îò ýôôåêòà
    Select Case mEffect
    Case 0
        ' ==========Áåç ýôôåêòà (ïðîñòî èçìåíÿåì ïðîçðà÷íîñòü ôîíà)=========
        ' Îïðåäåëÿåì êîýôôèöèåíò èçìåíåíèÿ àëüôà êîìïîíåíòû
        d = Fade * 255
        ' Ïðîõîä ïî áèòàì ðèñóíêà
        For y = 0 To h: For x = 0 To w
            ' Ïîëó÷àåì àëüôó
            a = (((imgSpectrumData(x, y) And &HFF000000) \ &H1000000) And &HFF&)
            ' Óìåíüøàåì
            a = a - d
            ' Îãðàíè÷èâàåì
            If a < 0 Then a = 0
            ' Âûäåëÿåì òîëüêî êîìïîíåíòû öâåòà
            c = imgSpectrumData(x, y) And &HFFFFFF
            ' Çàïèñûâàåì íàçàä ñ èçìåíåííîé àëüôîé
            If a > 127 Then
                imgSpectrumData(x, y) = c Or ((a - 256) * &H1000000)
            Else: imgSpectrumData(x, y) = c Or (a * &H1000000)
            End If
        Next: Next
    Case 1
        ' ===========================Ðàçìûòèå================================
        ' Îïðåäåëÿåì êîýôôèöèåíò èçìåíåíèÿ àëüôà êîìïîíåíòû
        d = Fade * 10
        ' Ïðîõîä ïî áèòàì ðèñóíêà
        For y = 0 To h: For x = 0 To w
            ' Ðàçìûâàåì âíóòðè (1,1,w-1,h-1)
            If x > 0 And y > 0 And x < w - 1 And y < h - 1 Then
                ' Îáíóëÿåì çíà÷åíèÿ íàêîïëåíèÿ êîìïîíåíò
                r = 0: g = 0: b = 0: a = 0
                ' Ïðîõîä ïî ñîñåäíèì ïèêñåëÿì
                For dy = -1 To 1: For dx = -1 To 1
                    ' Âûäåëÿåì êàæäóþ êîìïîíåíòó è çàïèñûâàåì â àêêóìóëÿòîðû
                    c = imgSpectrumData(x + dx, y + dy)
                    a = a + (((c And &HFF000000) \ &H1000000) And &HFF&)
                    r = r + (c And &HFF0000) \ &H10000
                    g = g + (c And &HFF00&) \ &H100
                    b = b + (c And &HFF)
                Next: Next
                ' Óñðåäíÿåì çíà÷åíèÿ â àêêóìóëÿòîðàõ è óìåíüøàåì àëüôó
                r = r \ 9: g = g \ 9: b = b \ 9: a = a \ 9 - d
                ' Îãðàíè÷èâàåì àëüôó ñíèçó
                If a < 0 Then a = 0
                ' Íàõîäèì çíà÷åíèÿ â RGB
                c = b Or (g * &H100&) Or (r * &H10000)
                ' Äîáàâëÿåì àëüôó
                If a > 127 Then
                    imgSpectrumData(x, y) = c Or ((a - 256) * &H1000000)
                Else: imgSpectrumData(x, y) = c Or (a * &H1000000)
                End If
                ' Èíà÷å îáíóëÿåì (ïîëíîñòüþ ïðîçðà÷íûé)
            Else: imgSpectrumData(x, y) = 0
            End If
        Next: Next
    Case 2
        ' ============================Ãîðåíèå================================
        ' Îïðåäåëÿåì êîýôôèöèåíò èçìåíåíèÿ àëüôà êîìïîíåíòû
        d = Fade * 64
        ' Êîïèðóåì áèòû ðèñóíêà â áóôåð
        Buf = imgSpectrumData
        ' Âû÷èñëÿåì ñäâèãè è øèðèíó â çàâèñèìîñòè îò îòîáðàæåíèÿ
        If mSymmetrical Then o = 0: s = w * 2 Else o = 0.5: s = w
        ' Ïðîõîä ïî áèòàì ðèñóíêà
        For y = 0 To h: For x = 0 To w
            ' Òðàíñôîðìèðóåì êîîðäèíàòó â çàâèñèìîñòè îò öåíòðà
            cx = x / s - o: cy = y / h - 0.5
            ' Íàõîäèì äëèíó îòíîñèòåëüíî öåíòðà
            r = Sqr(cx * cx + cy * cy)
            ' Íàõîäèì ðåçóëüòòèðóþùèé ïèêñåëü
            dx = (cx + o + 0.01 * cx * ((r - 1) / 0.5)) * s
            dy = (cy + 0.5 + 0.01 * cy * ((r - 1) / 0.5)) * h
            ' Íàõîäèì è óìåíüøàåì åãî àëüôó
            a = (((Buf(dx, dy) And &HFF000000) \ &H1000000) And &HFF&) - d
            ' Îãðàíè÷èâàåì àëüôó ñíèçó
            If a < 0 Then a = 0
            ' Âûäåëÿåì òîëüêî êîìïîíåíòû öâåòà
            c = Buf(dx, dy) And &HFFFFFF
            ' Çàïèñûâàåì íàçàä ñ èçìåíåííîé àëüôîé
            If a > 127 Then
                imgSpectrumData(x, y) = c Or ((a - 256) * &H1000000)
            Else: imgSpectrumData(x, y) = c Or (a * &H1000000)
            End If
        Next: Next
    End Select
End Sub
 
' Ïðîöåäóðà êîíâåðòèðóåò öåëûå çíà÷åíèÿ àìïëèòóä â êîìïëåêñíóþ ôîðìó ìèêøèðóÿ ïðàâûé è ëåâûé êàíàë,
' à òàêæå äåëàåò îêîííîå ïðåîáðàçîâàíèå
Private Sub ToComplex(Dat() As Integer, Out() As Complex)
    Dim i As Long, p As Long
    ' Ïðîõîä ïî èñòî÷íèêó
    For i = 0 To mFFTSize * 2 - 1 Step 2
        Out(p).r = ((CLng(Dat(i)) + Dat(i + 1)) / 65536) * Window(p): Out(p).i = 0
        p = p + 1
    Next
End Sub
 
' Ïðîöåäóðà îáíîâëÿåò ðàçìåðû áóôåðîâ
Private Sub UpdateBuffers()
    ReDim MapData(mFFTSize \ 2 - 1)
    ReDim Spectrum(mFFTSize - 1)
    ' Èíèöèàëèçèðóåì îêíî Õåììèíãà
    InitHamming
End Sub
 
' Ïðîöåäóðà ñîçäàåò îòîáðàæåíèå, äëÿ òîãî ÷òîáû íå âû÷èñëÿòü êàæäûé ðàç êîîðäèíàòû
Private Sub CreateMap()
    Dim o As Long, i1 As Long, i2 As Long, fr As Single, _
        d As Single, sa As Single, ea As Single, s As Single, ma As Single, _
        sn As Single, cs As Single, hs As Single, a As Single
    
    ' Íàõîäèì ðàäèóñ
    hs = frmMain.ScaleWidth / 2
    ' Âû÷èñëÿåì ðàçìåð îêòàâû â ïèêñåëÿõ
    OctAreaSize = hs * (2 * mOctaveCount - 1) / (mOctaveCount * mOctaveCount * 2)
    ' Çàäàåì óãîë ðàçâåðòêè
    ma = IIf(Symmetrical, 180, 360)
    ' Çàäàåì íà÷àëüíûå çíà÷åíèÿ äëÿ ðàäèóñà è èíäåêñà ñïåêòðà
    s = OctAreaSize: i1 = 1
    
    ' Ïðîõîä ïî îêòàâàì
    For o = 0 To mOctaveCount - 1
        ' Íàõîäèì èíäåêñ ñëåäóþùåé îêòàâû
        i2 = i1 * 2
        ' Íàõîäèì ïðèðàùåíèå óãëà
        d = ma / (i2 - i1)
        ' Óñòàíàâëèâàåì íà÷àëüíûé óãîë
        a = -90 + d / 2
        ' Åñëè ðàçìåð äóãè < 2 ïèêñåëåé è ðåæèì îòîáðàæåíèÿ êîëüöàìè, òî ðèñóåì ëèíèþ
        If 6.28318530717959 * s * (d / 360) < 2 And View = 0 Then
            Do While i1 < i2
                ' Íàõîäèì êîîðäèíàòû ëèíèè
                MapData(i1).IsLine = True
                MapData(i1).fa = Cos(a * 1.74532925199433E-02)
                MapData(i1).ta = Sin(a * 1.74532925199433E-02)
                a = a + d: i1 = i1 + 1
            Loop
        Else
            Do While i1 < i2
                ' Íàõîäèì óãëû
                MapData(i1).IsLine = False
                MapData(i1).fa = a - d / 2: MapData(i1).ta = d
                a = a + d: i1 = i1 + 1
            Loop
        End If
        ' Ñìåùåíèå íà ðàçìåð îêòàâû â ïèêñåëÿõ
        s = s + OctAreaSize
    Next
End Sub
 
' Ñîçäàíèå ïàëèòðû ïî óìîë÷àíèþ äëÿ êîëüöåâîãî îòîáðàæåíèÿ
Private Sub CreateDefaultRingPalette()
    Dim i As Long, a As Long
    ' Åñëè çàãðóæåíà âíåøíÿÿ ïàëèòðà, òî âûõîäèì
    If ExternalPalette Then Exit Sub
    ReDim Palette(255)
    For i = 0 To 255
        a = (Log((i / 128) + 1) / 0.693147180559945) / 2 * 255
        Palette(i) = ARGB(a, RGB(255 - i, 0, i))
    Next
End Sub
' Ñîçäàíèå ïàëèòðû ïî óìîë÷àíèþ äëÿ ñåêòîðíîãî îòîáðàæåíèÿ
Private Sub CreateDefaultSectorPalette()
    Dim i As Long, a As Long
    ' Åñëè çàãðóæåíà âíåøíÿÿ ïàëèòðà, òî âûõîäèì
    If ExternalPalette Then Exit Sub
    ReDim Palette(255)
    For i = 0 To 255
        a = (Log((i / 128) + 1) / 0.693147180559945) / 2 * 255
        Palette(i) = ARGB(255, RGB(255 - i, 0, i))
    Next
End Sub
' Áûñòðîå ïðåîáðàçîâàíèå Ôóðüå
Private Sub FFT(Dat() As Complex)
    Dim i As Long, j As Long, n As Long, K As Long, io As Long, ie As Long, in_ As Long, nn As Long
    Dim u As Complex, tp As Complex, tq As Complex, w As Complex, sr As Single, t As Complex
    
    If Not FFTInit Then InitFFT: FFTInit = True
    
    nn = mFFTSize \ 2: ie = mFFTSize
    For n = 1 To mFFTLog
        w = Coef(mFFTLog - n)
        in_ = ie \ 2: u.r = 1: u.i = 0
        For j = 0 To in_ - 1
            For i = j To mFFTSize - 1 Step ie
                io = i + in_
                tp.r = Dat(i).r + Dat(io).r: tp.i = Dat(i).i + Dat(io).i
                tq.r = Dat(i).r - Dat(io).r: tq.i = Dat(i).i - Dat(io).i
                Dat(io).r = tq.r * u.r - tq.i * u.i
                Dat(io).i = tq.i * u.r + tq.r * u.i
                Dat(i) = tp
            Next
            sr = u.r
            u.r = u.r * w.r - u.i * w.i
            u.i = u.i * w.r + sr * w.i
        Next
        ie = ie \ 2
    Next
    j = 1
    For i = 1 To mFFTSize - 1
        If i < j Then
            io = i - 1: in_ = j - 1: tp = Dat(in_)
            Dat(in_) = Dat(io)
            Dat(io) = tp
        End If
        K = nn
        Do While K < j
            j = j - K: K = K \ 2
        Loop
        j = j + K
    Next
    If mView = 0 Then sr = (4096 * mGain) / mFFTSize Else sr = 1 / mFFTSize
    For i = 0 To mFFTSize \ 2 - 1
        Dat(i).r = Dat(i).r * sr: Dat(i).i = Dat(i).i * sr
    Next
End Sub
 
' Èíèöèàëèçàöèÿ êîýôôèöèåíòîâ FFT
Private Sub InitFFT()
    Dim n As Long, vRcoef As Variant, vIcoef As Variant
    vRcoef = Array(-1#, 0#, 0.707106781186547 _
          , 0.923879532511287, 0.98078528040323, 0.995184726672197 _
          , 0.998795456205172, 0.999698818696204, 0.999924701839145 _
          , 0.999981175282601, 0.999995293809576, 0.999998823451702 _
          , 0.999999705862882, 0.999999926465718)
    vIcoef = Array(0#, -1#, -0.707106781186547 _
         , -0.38268343236509, -0.195090322016128, -9.80171403295606E-02 _
         , -0.049067674327418, -2.45412285229122E-02, -1.22715382857199E-02 _
         , -6.1358846491544E-03, -3.0679567629659E-03, -1.5339801862847E-03 _
         , -7.669903187427E-04, -3.834951875714E-04)
    For n = 0 To 13
        Coef(n).r = vRcoef(n): Coef(n).i = vIcoef(n)
    Next
End Sub
 
' Èíèöèàëèçàöèÿ êîýôôèöèåíòîâ îêíà Õåììèíãà
Private Sub InitHamming()
    Dim n As Long
    ReDim Window(mFFTSize - 1)
    For n = 0 To mFFTSize - 1
        Window(n) = 0.53836 - 0.46164 * Cos(6.28318530717959 * n / (mFFTSize - 1))
    Next
End Sub
Модуль modAudio:
Visual Basic
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
Option Explicit
 
' Ìîäóëü modAudio.bas äëÿ çàõâàòà çâóêà â ïðîãðàììå TrickSpectrum
' © Êðèâîóñ Àíàòîëèé Àíàòîëüåâè÷ (The trick), 2014
 
Public Type WAVEFORMATEX                                        ' Ñòðóêòóðà ôîðìàòà àóäèî
    wFormatTag As Integer                                       ' Òèï
    nChannels As Integer                                        ' Êîë-âî êàíàëîâ
    nSamplesPerSec As Long                                      ' ×àñòîòà äèñêðåòèçàöèè
    nAvgBytesPerSec As Long                                     ' Êîëè÷åñòâî áàéò â ñåêóíäó
    nBlockAlign As Integer                                      ' Âûðàâíèâàíèå áîêà äàííûõ â áàéòàõ
    wBitsPerSample As Integer                                   ' Áàéò íà âûáîðêó
    cbSize As Integer                                           ' Ðàçìåð äîï. äàííûõ
End Type
 
Public Type WAVEHDR                                             ' Ñòðóêòóðà çàãîëîâêà áóôåðà
    lpData As Long                                              ' Óêàçàòåëü íà äàííûå áóôåðà
    dwBufferLength As Long                                      ' Ðàçìåð áóôåðà â áàéòàõ
    dwBytesRecorded As Long                                     ' Êîëè÷åñòâî çàïèñàííûõ áàéòîâ
    dwUser As Long                                              ' Äàííûå ïîëüçîâàòåëÿ
    dwFlags As Long                                             ' Ôëàãè
    dwLoops As Long                                             ' Êîëè÷åñòâî çàêîëüöîâàííõ ïðîèãðûâàíèé
    lpNext As Long
    Reserved  As Long
End Type
 
Public Type BUFFER                                              ' Ñòðóêòóðà áóôåðà
    Data() As Integer                                           ' Äàííûå
    Header As WAVEHDR                                           ' Çàãîëîâîê
End Type
 
Public Declare Function waveInOpen Lib "winmm.dll" (lphWaveIn As Long, ByVal uDeviceID As Long, lpFormat As WAVEFORMATEX, ByVal dwCallback As Long, ByVal dwInstance As Long, ByVal dwFlags As Long) As Long
Public Declare Function waveInPrepareHeader Lib "winmm.dll" (ByVal hWaveIn As Long, lpWaveInHdr As WAVEHDR, ByVal uSize As Long) As Long
Public Declare Function waveInReset Lib "winmm.dll" (ByVal hWaveIn As Long) As Long
Public Declare Function waveInStart Lib "winmm.dll" (ByVal hWaveIn As Long) As Long
Public Declare Function waveInStop Lib "winmm.dll" (ByVal hWaveIn As Long) As Long
Public Declare Function waveInUnprepareHeader Lib "winmm.dll" (ByVal hWaveIn As Long, lpWaveInHdr As WAVEHDR, ByVal uSize As Long) As Long
Public Declare Function waveInClose Lib "winmm.dll" (ByVal hWaveIn As Long) As Long
Public Declare Function waveInGetErrorText Lib "winmm.dll" Alias "waveInGetErrorTextA" (ByVal err As Long, ByVal lpText As String, ByVal uSize As Long) As Long
Public Declare Function waveInAddBuffer Lib "winmm.dll" (ByVal hWaveIn As Long, lpWaveInHdr As WAVEHDR, ByVal uSize As Long) As Long
 
Public Const mSampleRate As Long = 44100                        ' ×àñòîòà äèñêðåòèçàöèè
Public Const BufSizeMS As Single = 0.03                         ' Ðàçìåð áóôåðà â ñåêóíäàõ
 
Public Const WAVE_MAPPER = -1&
Public Const CALLBACK_WINDOW = &H10000
Public Const WAVE_FORMAT_PCM = 1
Public Const MM_WIM_DATA = &H3C0
 
Dim hWave As Long                                               ' Äåñêðèïòîð çàïèñûâàþùåãî óñòðîéñòâà
Dim Fmt As WAVEFORMATEX                                         ' Ôîðìàò çàïèñè
Dim Buffers() As BUFFER                                         ' Áóôåðû
 
' Ôóíêöèÿ èíèöèàëèçèðóåò çàïèñü
Public Function InitCapture() As Boolean
    Dim ret As Long, msg As String, i As Long, count As Long
    
    ' Çàäàåì ôîðìàò çàïèñè
    With Fmt
        .cbSize = 0
        .wFormatTag = WAVE_FORMAT_PCM
        .wBitsPerSample = 16
        .nSamplesPerSec = mSampleRate
        .nChannels = 2
        .nBlockAlign = .nChannels * .wBitsPerSample / 8
        .nAvgBytesPerSec = .nSamplesPerSec * .nBlockAlign
    End With
    
    ' Âû÷èñëÿåì ðàçìåð áóôåðà â âûáîðêàõ
    count = Fmt.nAvgBytesPerSec * BufSizeMS
    count = count - (count Mod Fmt.nBlockAlign)
    
    ' Îòêðûâàåì óñòðîéñòâî çàïèñè
    ret = waveInOpen(hWave, WAVE_MAPPER, Fmt, frmMain.hwnd, 0, CALLBACK_WINDOW)
    
    If ret Then ShowMessage ret: Exit Function
    
    ' 4 áóôåðà
    ReDim Buffers(3)
    
    ' Ïîäãîòîâêà áóôåðîâ
    For i = 0 To UBound(Buffers)
         With Buffers(i)
             ReDim .Data(count - 1)
             .Header.lpData = VarPtr(.Data(0))
             .Header.dwBufferLength = count * 2
             .Header.dwFlags = 0
             .Header.dwLoops = 0
             ret = waveInPrepareHeader(hWave, .Header, Len(.Header))
             If ret Then ShowMessage ret: Exit Function
         End With
    Next i
    
    ' Îòïðàâêà áóôåðîâ óñòðîéñòâó
    For i = 0 To UBound(Buffers)
        ret = waveInAddBuffer(hWave, Buffers(i).Header, Len(Buffers(i).Header))
        If ret Then ShowMessage ret: Exit Function
    Next i
    
    ' Íà÷èíàåì çàïèñü
    ret = waveInStart(hWave)
    If ret Then ShowMessage ret: Exit Function
    
    ' Óñïåøíî
    InitCapture = True
End Function
 
' Ïðîöåäóðà îñòàíàâëèâàåò çàïèñü
Public Sub EndCapture()
    Dim i As Long
    ' Ñáðîñ óñòðîéñòâà è âîçâðàùåíèå âñåõ áóôåðîâ ïðèëîæåíèþ
    waveInReset hWave
    ' Îñòàíîâêà çàïèñè
    waveInStop hWave
    
    ' ÎÑâîáîæäåíèå çàãîëîâêîâ áóôåðîâ
    For i = 0 To UBound(Buffers)
        waveInUnprepareHeader hWave, Buffers(i).Header, Len(Buffers(i).Header)
    Next
    
    ' Çàêðûòèå óñòðîéñòâà çàïèñè
    waveInClose hWave
End Sub
 
' Ôóíêöèÿ âûçûâàåòñÿ ïðè î÷åðåäíîì çàïîëíåííîì áóôåðå
Public Function OnCapture(Hdr As WAVEHDR) As Boolean
    Dim i As Long
    ' Ïîëó÷àåì èíäåêñ áóôåðà
    i = modAudio.GetBufferIndex(Hdr.lpData)
    If i = -1 Then Exit Function
    ' Âûçûâàåì îòðèñîâêó
    modMain.Draw modAudio.Buffers(i).Data
    ' Îòïðàâêà áóôåðà óñòðîéñòâó
    waveInAddBuffer hWave, Buffers(i).Header, Len(Buffers(i).Header)
End Function
 
' Ôóíêöèÿ âîçâðàùàåò èíäåêñ áóôåðà ïî åãî óêàçàòåëþ
Private Function GetBufferIndex(ByVal Ptr As Long) As Long
    Dim i As Long
    For i = 0 To UBound(Buffers)
        If Buffers(i).Header.lpData = Ptr Then GetBufferIndex = i: Exit Function
    Next
    GetBufferIndex = -1
End Function
 
' Ïðîöåäóðà ïîêàçûâàåò ñîîáùåíèå îá îøèáêå
Private Sub ShowMessage(ByVal Code As Long)
    Dim msg As String
    msg = Space(255)
    waveInGetErrorText Code, msg, Len(msg)
    MsgBox "Error capture." & vbNewLine & msg
End Sub
Модуль modGraphics:
Visual Basic
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
Option Explicit
 
' Ìîäóëü modGraphics.bas äëÿ èíèöèàëèçàöèè è ðàáîòû GDI+ â ïðîãðàììå TrickSpectrum
' © Êðèâîóñ Àíàòîëèé Àíàòîëüåâè÷ (The trick), 2014
 
Public Type GdiplusStartupInput
    GdiplusVersion As Long
    DebugEventCallback As Long
    SuppressBackgroundThread As Long
    SuppressExternalCodecs As Long
End Type
 
Public Declare Function GdiplusStartup Lib "gdiplus" (token As Long, inputbuf As GdiplusStartupInput, Optional ByVal outputbuf As Long = 0) As Long
Public Declare Function GdipCreateFromHDC Lib "gdiplus" (ByVal hdc As Long, Graphics As Long) As Long
Public Declare Function GdipCreatePen1 Lib "gdiplus" (ByVal color As Long, ByVal Width As Single, ByVal unit As Long, Pen As Long) As Long
Public Declare Function GdipDeleteGraphics Lib "gdiplus" (ByVal Graphics As Long) As Long
Public Declare Function GdiplusShutdown Lib "gdiplus" (ByVal token As Long) As Long
Public Declare Function GdipCreateSolidFill Lib "gdiplus" (ByVal ARGB As Long, Brush As Long) As Long
Public Declare Function GdipSetSmoothingMode Lib "gdiplus" (ByVal Graphics As Long, ByVal SmoothingMd As Long) As Long
Public Declare Function GdipGetSmoothingMode Lib "gdiplus" (ByVal Graphics As Long, SmoothingMd As Long) As Long
Public Declare Function GdipDeleteBrush Lib "gdiplus" (ByVal Brush As Long) As Long
Public Declare Function GdipSetSolidFillColor Lib "gdiplus" (ByVal Brush As Long, ByVal ARGB As Long) As Long
Public Declare Function GdipCreateBitmapFromScan0 Lib "gdiplus" (ByVal Width As Long, ByVal Height As Long, ByVal stride As Long, ByVal PixelFormat As Long, scan0 As Any, Bitmap As Long) As Long
Public Declare Function GdipDisposeImage Lib "gdiplus" (ByVal image As Long) As Long
Public Declare Function GdipFillEllipse Lib "gdiplus" (ByVal Graphics As Long, ByVal Brush As Long, ByVal x As Single, ByVal y As Single, ByVal Width As Single, ByVal Height As Single) As Long
Public Declare Function GdipGraphicsClear Lib "gdiplus" (ByVal Graphics As Long, ByVal lColor As Long) As Long
Public Declare Function GdipGetImageGraphicsContext Lib "gdiplus" (ByVal image As Long, Graphics As Long) As Long
Public Declare Function GdipDrawImageI Lib "gdiplus" (ByVal Graphics As Long, ByVal image As Long, ByVal x As Long, ByVal y As Long) As Long
Public Declare Function GdipDrawImageRectI Lib "gdiplus" (ByVal Graphics As Long, ByVal image As Long, ByVal x As Long, ByVal y As Long, ByVal Width As Long, ByVal Height As Long) As Long
Public Declare Function GdipDrawLine Lib "gdiplus" (ByVal Graphics As Long, ByVal Pen As Long, ByVal X1 As Single, ByVal Y1 As Single, ByVal X2 As Single, ByVal Y2 As Single) As Long
Public Declare Function GdipDeletePen Lib "gdiplus" (ByVal Pen As Long) As Long
Public Declare Function GdipSetPenColor Lib "gdiplus" (ByVal Pen As Long, ByVal ARGB As Long) As Long
Public Declare Function GdipDrawArc Lib "gdiplus" (ByVal Graphics As Long, ByVal Pen As Long, ByVal x As Single, ByVal y As Single, ByVal Width As Single, ByVal Height As Single, ByVal startAngle As Single, ByVal sweepAngle As Single) As Long
Public Declare Function GdipSetPenWidth Lib "gdiplus" (ByVal Pen As Long, ByVal Width As Single) As Long
Public Declare Function GdipSetPenMode Lib "gdiplus" (ByVal Pen As Long, ByVal penMode As Long) As Long
Public Declare Function GdipFillPie Lib "gdiplus" (ByVal Graphics As Long, ByVal Brush As Long, ByVal x As Single, ByVal y As Single, ByVal Width As Single, ByVal Height As Single, ByVal startAngle As Single, ByVal sweepAngle As Single) As Long
Public Declare Function GdipLoadImageFromFile Lib "gdiplus" (ByVal FileName As Long, image As Long) As Long
Public Declare Function GdipGetImagePixelFormat Lib "gdiplus" (ByVal image As Long, PixelFormat As Long) As Long
Public Declare Function GdipGetImageWidth Lib "gdiplus" (ByVal image As Long, Width As Long) As Long
Public Declare Function GdipBitmapGetPixel Lib "gdiplus" (ByVal Bitmap As Long, ByVal x As Long, ByVal y As Long, color As Long) As Long
 
Public Const UnitPixel = 2, _
             SmoothingModeAntiAlias = 4, _
             SmoothingModeHighSpeed = 1, _
             PixelFormat32bppARGB = &H26200A, _
             PixelFormat32bppPARGB = &HE200B, _
             FillModeAlternate = 0, _
             CombineModeExclude = 4, _
             PenAlignmentInset = 1
             
Dim token As Long
Dim si As GdiplusStartupInput
 
' Èíèöèàëèçàöèÿ GDI+
Public Function InitGDIPlus() As Boolean
    si.GdiplusVersion = 1
    InitGDIPlus = GdiplusStartup(token, si) = 0
End Function
 
' Äåèíèöèàëèçàöèÿ GDI+
Public Sub UninitGDIPlus()
    GdiplusShutdown token
End Sub
 
' Âîçâðàùàåò öâåò, ïåðåäàííûé â êà÷åñòâå ïàðàìåòðà ñ ïîäìåøèâàíèåì àëüôà êîìïîíåíòû
Public Function ARGB(ByVal Alpha As Byte, ByVal Col As Long) As Long
    If Alpha > 127 Then
        ARGB = Col And &HFFFFFF Or ((CLng(Alpha) - 256) * &H1000000)
    Else: ARGB = Col And &HFFFFFF Or (CLng(Alpha) * &H1000000)
    End If
End Function
модуль modMenu:
Visual Basic
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
Option Explicit
 
' Ìîäóëü modMenu.bas äëÿ ñîçäàíèÿ ìåíþ â ïðîãðàììå TrickSpectrum
' © Êðèâîóñ Àíàòîëèé Àíàòîëüåâè÷ (The trick), 2014
 
Public Type POINTAPI
    x As Long
    y As Long
End Type
 
Public Declare Function CreatePopupMenu Lib "user32" () As Long
Public Declare Function DestroyMenu Lib "user32" (ByVal hMenu As Long) As Long
Public Declare Function AppendMenu Lib "user32" Alias "AppendMenuA" (ByVal hMenu As Long, ByVal wFlags As Long, ByVal wIDNewItem As Long, ByVal lpNewItem As String) As Long
Public Declare Function TrackPopupMenuEx Lib "user32" (ByVal hMenu As Long, ByVal un As Long, ByVal n1 As Long, ByVal n2 As Long, ByVal hwnd As Long, lpTPMParams As Any) As Long
Public Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
Public Declare Function CheckMenuItem Lib "user32" (ByVal hMenu As Long, ByVal wIDCheckItem As Long, ByVal wCheck As Long) As Long
Public Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
 
Public Const WM_CLOSE = &H10
Public Const MF_CHECKED = &H8&
Public Const MF_UNCHECKED = &H0&
Public Const MF_APPEND = &H100&
Public Const TPM_LEFTALIGN = &H0&
Public Const MF_DISABLED = &H2&
Public Const MF_GRAYED = &H1&
Public Const MF_SEPARATOR = &H800&
Public Const MF_STRING = &H0&
Public Const MF_POPUP = &H10&
Public Const MF_BYPOSITION = &H400&
 
' Äåñêðèïòîðû ìåíþ
Public mnuMain As Long, _
       mnuOct As Long, _
       mnuTransparency As Long, _
       mnuFade As Long, _
       mnuGain As Long, _
       mnuEffects As Long, _
       mnuView As Long
 
' Ïðîöåäóðà èíèöèàëèçèðóåò âñïëûâàþùåå ìåíþ
Public Sub CreateMenu()
    Dim i As Long, z As Long
    
    mnuMain = CreatePopupMenu
    mnuOct = CreatePopupMenu
    mnuTransparency = CreatePopupMenu
    mnuFade = CreatePopupMenu
    mnuGain = CreatePopupMenu
    mnuEffects = CreatePopupMenu
    mnuView = CreatePopupMenu
    
    AppendMenu mnuMain, MF_STRING Or MF_POPUP, mnuView, "View"
    AppendMenu mnuMain, MF_STRING, z, "Symmetrical": z = z + 1
    AppendMenu mnuMain, MF_STRING, z, "Smoothing": z = z + 1
    AppendMenu mnuMain, MF_STRING, z, "Transparent": z = z + 1
    AppendMenu mnuMain, MF_STRING, z, "About...": z = z + 1
    AppendMenu mnuMain, MF_STRING Or MF_POPUP, mnuOct, "Octaves count"
    AppendMenu mnuMain, MF_STRING Or MF_POPUP, mnuTransparency, "Background opaque"
    AppendMenu mnuMain, MF_STRING Or MF_POPUP, mnuFade, "Fade"
    AppendMenu mnuMain, MF_STRING Or MF_POPUP, mnuGain, "Gain"
    AppendMenu mnuMain, MF_STRING Or MF_POPUP, mnuEffects, "Effects"
    AppendMenu mnuMain, MF_SEPARATOR, 0, vbNullString
    AppendMenu mnuMain, MF_STRING, z, "Load palette...": z = z + 1
    AppendMenu mnuMain, MF_SEPARATOR, 0, vbNullString
    AppendMenu mnuMain, MF_STRING, z, "Exit": z = z + 1
 
    AppendMenu mnuEffects, MF_STRING, 500, "None"
    AppendMenu mnuEffects, MF_STRING, 501, "Blur"
    AppendMenu mnuEffects, MF_STRING, 502, "Fire"
 
    AppendMenu mnuView, MF_STRING, 600, "Rings"
    AppendMenu mnuView, MF_STRING, 601, "Sectors"
    
    For i = 1 To 10
        If i > 1 Then AppendMenu mnuOct, MF_STRING, 100 + i, CStr(i)
        AppendMenu mnuTransparency, MF_STRING, 200 + i, Format(i / 10, "###%")
        AppendMenu mnuFade, MF_STRING, 300 + i, Format(i * i / 100, "###%")
        AppendMenu mnuGain, MF_STRING, 400 + i, Format(i, "###%")
    Next
    
End Sub
 
' Ïðîöåäóðà óäàëÿåò ìåíþ
Public Sub DeleteMenu()
    DestroyMenu mnuMain
    DestroyMenu mnuOct
    DestroyMenu mnuTransparency
    DestroyMenu mnuFade
    DestroyMenu mnuGain
    DestroyMenu mnuEffects
    DestroyMenu mnuView
End Sub
 
' Ôóíêöèÿ âûçûâàåòñÿ ïðè ïðàâîì êëèêå ìûøüþ íà îêíå
Public Function OnRButtonUp(ByVal x As Long, ByVal y As Long) As Long
    TrackPopupMenuEx mnuMain, TPM_LEFTALIGN, x, y, frmMain.hwnd, ByVal 0&
End Function
 
' Ôóíêöèÿ âûçûâàåòñÿ ïðè âûáîðå ïóíêòà ìåíþ
Public Function OnMenuClick(ByVal itemID As Long) As Long
    Dim s As String
    Select Case itemID
    Case 0 ' Symmetrical
        modMain.Symmetrical = Not modMain.Symmetrical
    Case 1 ' Smoothing
        modMain.Smoothing = Not modMain.Smoothing
    Case 2 ' Transparent
        modMain.Transparent = Not modMain.Transparent
    Case 3 ' About
        frmAbout.Show vbModal
    Case 4 ' LoadPalette
        s = modOpenFileName.GetFile()
        If Len(s) Then modMain.LoadPalette s
    Case 5 ' Exit
        Quit
        PostMessage frmMain.hwnd, WM_CLOSE, 0, 0
    Case 101 To 110 ' Octave count
        modMain.OctaveCount = itemID - 100
    Case 201 To 210 ' Background opaque
        modMain.Transparency = (itemID - 200) / 10
    Case 301 To 310 ' Fade
        modMain.Fade = ((itemID - 300) ^ 2) / 100
    Case 401 To 410 ' Gain
        modMain.Gain = itemID - 400
    Case 500 To 510 ' Effect
        modMain.Effect = itemID - 500
    Case 600 To 610 ' View
        modMain.View = itemID - 600
    End Select
End Function
Модуль modOpenFileName:
Visual Basic
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
Option Explicit
 
' Ìîäóëü modOpenFileName.bas äëÿ âûçîâà äèàëîãîâîãî îêíà îòêðûòèÿ ôàéëà â ïðîãðàììå TrickSpectrum
' © Êðèâîóñ Àíàòîëèé Àíàòîëüåâè÷ (The trick), 2014
 
Public Type OPENFILENAME
    lStructSize As Long
    hwndOwner As Long
    hInstance As Long
    lpstrFilter As Long
    lpstrCustomFilter As Long
    nMaxCustFilter As Long
    nFilterIndex As Long
    lpstrFile As Long
    nMaxFile As Long
    lpstrFileTitle As Long
    nMaxFileTitle As Long
    lpstrInitialDir As Long
    lpstrTitle As Long
    flags As Long
    nFileOffset As Integer
    nFileExtension As Integer
    lpstrDefExt As Long
    lCustData As Long
    lpfnHook As Long
    lpTemplateName As Long
End Type
 
Public Declare Function GetOpenFileName Lib "comdlg32.dll" Alias "GetOpenFileNameW" (pOpenfilename As OPENFILENAME) As Long
 
' Îòêðûòü äèàëîã âûáîðà ôàéëà è ïîëó÷èòü èìÿ âûáðàííîãî ôàéëà
Public Function GetFile() As String
    Dim ofn As OPENFILENAME
    Dim Out As String
    Dim i As Long
    
    ofn.nMaxFile = 260
    Out = String(260, vbNullChar)
    ofn.hwndOwner = frmMain.hwnd
    ofn.lpstrTitle = StrPtr("Open image")
    ofn.lpstrFile = StrPtr(Out)
    ofn.lStructSize = Len(ofn)
    ofn.lpstrFilter = StrPtr("PNG with alpha channel" & vbNullChar & "*.png" & vbNullChar)
    If GetOpenFileName(ofn) Then
        i = InStr(1, Out, vbNullChar, vbBinaryCompare)
        If i Then GetFile = Left$(Out, i - 1)
    End If
End Function
Модуль modWndProc:
Visual Basic
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
Option Explicit
 
' Ìîäóëü modWndProc.bas äëÿ ñàáêëàññèíãà îêíà â ïðîãðàììå TrickSpectrum
' © Êðèâîóñ Àíàòîëèé Àíàòîëüåâè÷ (The trick), 2014
 
Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Public Declare Function GetWindowLong Lib "user32.dll" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
Public Declare Function SetWindowPos Lib "user32" (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
Public Declare Function UpdateLayeredWindow Lib "user32.dll" (ByVal hwnd As Long, ByVal hdcDst As Long, pptDst As Any, psize As Any, ByVal hdcSrc As Long, pptSrc As Any, ByVal crKey As Long, pblend As Long, ByVal dwFlags As Long) As Long
Public Declare Function ReleaseCapture Lib "user32" () As Long
Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Public Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Public Declare Function CreateEllipticRgn Lib "gdi32" (ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
Public Declare Function SetWindowRgn Lib "user32" (ByVal hwnd As Long, ByVal hRgn As Long, ByVal bRedraw As Boolean) As Long
Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
 
Public Const HWND_TOPMOST As Long = -1
Public Const WS_EX_LAYERED = &H80000
Public Const GWL_EXSTYLE As Long = -20
Public Const GWL_WNDPROC = (-4)
Public Const ULW_ALPHA = &H2
Public Const AB_32Bpp255 = 33488896
Public Const HTCAPTION As Long = 2
Public Const WM_NCRBUTTONUP = &HA5
Public Const WM_NCLBUTTONDBLCLK = &HA3
Public Const WM_COMMAND = &H111
Public Const WM_NCHITTEST = &H84
Public Const WM_SIZE = &H5
Public Const SWP_NOSIZE = &H1
Public Const SWP_NOMOVE = &H2&
 
Dim PrevWndProc As Long
 
' Ïðîöåäóðà ñàáêëàññèò îêíî
Public Sub Hook()
    SetWindowPos frmMain.hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE Or SWP_NOMOVE
    PrevWndProc = SetWindowLong(frmMain.hwnd, GWL_WNDPROC, AddressOf WndProc)
End Sub
 
' Ïðîöåäóðà ñíèìàåò ñàáêëàññèíã ñ îêíà
Public Sub Unhook()
    SetWindowLong frmMain.hwnd, GWL_WNDPROC, PrevWndProc
End Sub
 
' Îêîííàÿ ôóíêöèÿ îêíà
Private Function WndProc(ByVal hwnd As Long, ByVal msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Select Case msg
    Case MM_WIM_DATA
        ' Ïðè çàïîëíåíèè î÷åðåäíîãî áóôåðà
        Dim Hdr As WAVEHDR
        ' Êîïèðóåì çàãîëîâîê
        CopyMemory Hdr, ByVal lParam, Len(Hdr)
        ' Âûçûâàåì ôóíêöèþ
        OnCapture Hdr
    Case WM_NCHITTEST
        ' Îïðåäåëåíèå ïîëîæåíèÿ ìûøè
        WndProc = HTCAPTION
    Case WM_NCRBUTTONUP
        ' Îòïóñêàíèå ïðàâîé êíîïêè ìûøè â íåêëèåíòñêîé îáëàñòè
        WndProc = OnRButtonUp(IIf(lParam And &H8000&, lParam Or &HFFFF0000, lParam And &HFFFF&), lParam \ &H10000)
    Case WM_COMMAND
        ' Êëèê ïî ìåíþ
        If (wParam And &HFFFF0000) = 0 Then
            ' Åñëè ïî ìåíþ, òî âûçîâ ôóíêöèè
            WndProc = OnMenuClick(wParam)
        Else: WndProc = CallWindowProc(PrevWndProc, hwnd, msg, wParam, lParam)
        End If
    Case WM_SIZE
        ' Ïðè èçìåíåíèè ðàçìåðà
        OnResize
    Case Else: WndProc = CallWindowProc(PrevWndProc, hwnd, msg, wParam, lParam)
    End Select
End Function
Форма frmAbout:
Visual Basic
1
2
3
4
5
6
7
8
Option Explicit
 
Private Sub Form_Load()
    Me.Caption = "About " & App.Title
    lblTitle.Caption = App.Title
    lblVersion.Caption = "Version " & App.Major & "." & App.Minor & "." & App.Revision
    SetWindowPos Me.hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE Or SWP_NOMOVE
End Sub
В архиве небольшой набор палитр.
Видео
Миниатюры
Нажмите на изображение для увеличения
Название: Безымянный.png
Просмотров: 652
Размер:	128.8 Кб
ID:	2175  
Вложения
Тип файла: rar TrickSpectrum.rar (108.5 Кб, 687 просмотров)
Метки vb
Размещено в Без категории
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Всего комментариев 1
Комментарии
  1. Старый комментарий
    Аватар для Pro_grammer
    Я сегодня без претензий
    Классно работает на winXP sp3!
    Запись от Pro_grammer размещена 27.03.2014 в 06:59 Pro_grammer вне форума
 
Новые блоги и статьи
Часы электронные
Uhbif79 12.08.2026
Выкладываю программу часов. Программа позволяет: 1. Использовать системное время и дату, 2. Есть возможность вводить время и дату вручную. 3. Реализованы 2 будильника: начало и конец рабочего дня. . . .
Часы с будильником на основе класса QLCDNumber
Uhbif79 12.08.2026
Всем добрый день, выкладываю программу часов с будильником на основе класса QLCDNumber. Здесь я пробовал самостоятельно создавал классы, впервые столкнулся с видимостью переменной одного класса из. . .
Установка MinGW GCC 16.2 и CMake
8Observer8 10.08.2026
VK Видео: https:/ / vkvideo. ru/ video-240781534_456239017 YouTube: eY5-5PyI9NM Текстовая версия
Неделя из жизни имитационной модели склада: мои кривые руки растут, откуда надо
anaschu 10.08.2026
Неделя из жизни имитационной модели склада: как я почти написал неправильную логику и что с этим делать Работаю сейчас над учебно-рабочим проектом: строю в AnyLogic имитационную модель процессов. . .
Калькулятор для расчета родства
russiannick 07.08.2026
1. Задача: Создать калькулятор для расчета родства. Родственных связей существует 8 ступеней, такие как: p - отец P - мать q - муж Q - жена b - брат B - сестра s - сын S - дочь
Мир по моей воле
kumehtar 07.08.2026
Когда-то кажется, что всё просто. Ты весь такой светлый. Причиняешь добро. Борешься за справедливость в этом тёмном мире. Потом начинаешь замечать одну неприятную вещь. Почти каждый хороший. . .
Кредитный калькулятор
Maks 05.08.2026
Решение задачи по прикладной информатике средствами 1С. Задача: Напишите приложение-калькулятор, которое помогает рассчитывать параметры кредита для аннуитетного и дифференцированного видов. . .
У нас сейчас поговорку "Опять 25" нужно переделать на "Опять +35".
kumehtar 04.08.2026
С ностальгией вспоминаю времена моего детства, когда у нас и правда +25 - была максимальная температура летом. Раньше +25 °C реально казались вершиной жары, когда можно было весь день пропадать на. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru