Cześć.
Nadal męczę się z poprawieniem kodu źródłowego mojej wtyczki WLX dla Total Commandera, która jest pisana w WinAPI i jest to odtwarzacz modułów muzycznych z użyciem bass.dll. Specjalnie aby testy mogły trwać krócej, przekompilowałem wersję tak aby bass.dll był czytany z dysku w katalogu tam gdzie jest plugin, a nie z zasobów dllki. Niestety nadal mam problem.
Poprawiłem inne błedy powodujące prawdopodobnie memleaky, ale kiedy dodam jeden button na próbę to po odtworzeniu ponad 3200 modułów z zestawu liczącego 442 pliki, które zmienia symulując naciśnięcia klawiszy moj testowy program. Button ten znika. W konsekwencji powodwał by też inne problemy z rysowaniem. Wcześniej @kAzek przeglądal mój kod i narzędziem do badania zachowań wycieków GDI, którego ja nie ogarniam, ustalił że wedlug niego wycieków być niepowinno. Jednak mimo tego plugin w wersji kodu jaki mi odesłal, po odtwrozeniu okoló 6000 plików wykrzaczał się z kolorami i po zamnkięciu okna podglądu już się nie otwierał sypiąc wyjątkami av. Także kombinuję na nowo.
Button tworzę i subclassuje tak:
PlayBtnHandle := CreateWindow('Static', '',
WS_CHILD or WS_VISIBLE or SS_NOTIFY,
GetControlLeft(ModulePositionSBHandle),
GetControlTop(ModulePositionSBHandle) + GetControlHeight(ModulePositionSBHandle) + Controls_Vert_Distance,
Buttons_Icon_Size, Buttons_Icon_Size, ControlsGBHandle, IDC_PLAYBTN, HInstance, nil);
//...
POldStaticProc1 := Pointer(SetWindowLong(PlayBtnHandle, GWL_WNDPROC, Integer(MakeObjectInstance(NewStaticProc1))));
Użyte funkcje do ustalania rozmiarów i połóżeń kontrolki oraz subclassowania są na pewno ok. Bo wiadomo, żależy mi by móc odtwarzać bez wycieków i błedów wiele plików po sobie. Stąd odtworzenie tylko 3200 razy bez błędów nie spełnia założeń
Natomiast ikonki z zasobów ładuję tak jak poniżej i "przekonwertowuję" na typ HBITMAP w taki sposób:
//...
var
BitmapsHandleArr : array[1..3] of HBITMAP;
//...
procedure TPluginObj.LoadImages;
var
I : integer;
IconH : HICON;
IconInfo : TIconInfo;
begin
for I := Low(BitmapsHandleArr) to High(BitmapsHandleArr) do
begin
IconH := LoadImage(HInstance, MAKEINTRESOURCE(GFX_BASE + (I mod 100)), IMAGE_ICON, Icon_Size, Icon_Size, LR_DEFAULTCOLOR);
GetIconInfo(IconH, IconInfo);
DestroyIcon(IconH);
BitmapsHandleArr[I] := IconInfo.hbmColor;
end;
end;
Powyższa procedura jest wywoływana tylko raz przy tworzeniu kontrolek pluginu. Do jej kodu zostało dodane DestroyIcon
. Gdyż bez niego, kiedy była ona wywoływana nawet bez zastosowania buttonó, to plugin potrafił się wysypać po okolo 700 odtworzeniach plików. A oto kod na rysowanie grafiki, na konkretnie na razie buttonie do odtwarzania jest wykonane w taki sposób:
procedure TPluginObj.NewStaticProc1(var AMessage : TMessage);
var
AHWnd : HWND;
HBmp : HBITMAP;
BMInfo : BITMAP;
DC, DCMem : HDC;
PS : TPaintStruct;
begin
with AMessage do
begin
case Msg of
WM_PAINT :
begin
AHWnd := PlayBtnHandle;
HBmp := BitmapsHandleArr[1];
DC := BeginPaint(AHWnd, PS);
DCMem := CreateCompatibleDC(DC);
GetObject(HBmp, SizeOf(BMInfo), @BMInfo);
SelectObject(DCMem, HBmp);
TransparentBlt(DC, 0, 0, BMInfo.bmWidth, BMInfo.bmHeight, DCMem, 0, 0, BMInfo.bmWidth, BMInfo.bmHeight, ColorToRGB(clBlack));
DeleteObject(HBmp);
DeleteDC(DCMem);
EndPaint(AHWnd, PS);
Result := 0;
Exit;
end;
wM_SETCURSOR :
begin
SetCursor(LoadCursor(0, IDC_HAND));
Result := 0;
Exit;
end;
end;
Result := CallWindowProc(POldStaticProc1, PlayBtnHandle, Msg, WParam, LParam);
end;
end;
Obecnie plugin został zmieniony tak, że okno podglądu jest tworzeone za każdym razem, gdy wczytujemy jakiś plik. Czyli eksportowane z dllki funkcje ListLoadNext
oraz ListLoadNextW
są zakomentowane i plugin ich nie udostępnia. No i jak pisałem po odtworzeniu 3200 plików z mojego zestawu testowego button znika. A kiedy testuje inne kontorlki bez jego rysowania wszystko jest raczej ok. Czy coś tutaj należy do kodu dodać, poprawić? Prosil bym o podpowiedzi i przykłady kodów źródlowych.
I dodam, że bitmapa raczej musi być rysowana tak, a nie ustawiana przez STM_SETIMAGE
gdyż chcę aby miałą przezroczyste tło, gdyż domyślnie jest czarne, a docelowo user będze mógł zmieniać je checkboxem jeżeli zdefiniował własne kolory dla Listera w ustawieniach Total Commandera. Z mojego googlowania wynikało że raczej jest ok, a pewne przykłady jakie znalazłem na rysowanie bitmap w WM_PAINT
nie rysowały mi nic tutaj, bo chyba oparte były na rysowaniu na głownycn oknach, a nie subclassowanych kontrolkach, jak tutaj. Sorry za rozpiskę. Z góry dziękuję za pomoc.