Ru-Board.club
← Вернуться в раздел «Прикладное программирование»

» Вопросы по Delphi (до версии 2009) - часть 6

Автор: idiMAN
Дата сообщения: 13.08.2012 22:06
Ichigo2
Ну всё правильно твоя программа работает!!!

Судя по твоему скриншоту pos(_tag,rec[i].tag)=0, так и должно быть, ведь подстрока _tag не будет найдена в строке rec[i].tag

Обрати внимание на концевой пробел в _tag, у тебя после буквы "н" в слове "один" стоит пробел. Его на скриншоте отчётливо видно.
Т.е. подстрока "один " не содержится в строке "*один*два*", т.е pos=0
Автор: Ichigo2
Дата сообщения: 13.08.2012 22:17
idiMAN, заработало!11
Вы просто гений, уважаемый! Глаз-алмаз!
Пропустил _tag через TrimRight и pos выдает заветную двоечку.
Добра вам.

Автор: eddoc
Дата сообщения: 14.08.2012 07:44
Ichigo2

Цитата:
Пропустил _tag через TrimRight

что мешает использовать более универсальную функцию Trim, к тому же и писАть короче
Автор: Maks150988
Дата сообщения: 15.08.2012 21:12
Всем привет. Кому не сложно и кто "собаку съел" на массивах гляньте плиз мой небольшой демо пример. Я сделал функции по работе с массивом но не уверен что все корректно с освобождение памяти при удалении элементов. Ну итак пройдитесь по функциям и скажите что где можно упростить или оптимизировать. Образаюсь еще и потому что при изменении элемента массива после нескольких раз программы тупо вылетает. С отладчиком все равно не умею работать так что беспонтово глядеть внего приходится своими знаниями стараться избегать глупых ошибок при работе с указателями.

MyArrayTest.zip
Автор: Frodo_Torbins
Дата сообщения: 16.08.2012 11:51
Maks150988
В CopyArrayItem написан бред. А в UpdateArrayItem нужна оптимизация.
Автор: Maks150988
Дата сообщения: 16.08.2012 20:16
Frodo_Torbins
А как правильнее в CopyArrayItem хотя бы? =)
Автор: Frodo_Torbins
Дата сообщения: 16.08.2012 21:10
Maks150988
Все сильно зависит от логики, которую нужно реализовать. Если строки всегда должны копироваться, то просто добавить проверку на нуль в SrcInfo.pszText. Но какой тогда смысл возится с такими указателями, если точно такой же результат можно получить, применив WideString? Если нужно копировать указатель, то тогда непонятно когда можно удалять строку. Хоть счетчик ссылок добавляй.
Автор: Maks150988
Дата сообщения: 16.08.2012 21:38
Frodo_Torbins
Да, мненужно, чтобы строки всегда копировались. Где добавить проверку? Перед CopyMemory или AllocArrayItem? А может сразу проверить на nil и выполнить их после успешности проверки?
Автор: FalseMaster
Дата сообщения: 17.08.2012 04:20
Обращаюсь к тем, кто на данный момент пользуется D2007 с последним хотфиксом (Апрель 2008), устанавливающимся из запароленного архива "RADStudio2007apr08hotfix.exe". Мне очень нужны обновлённые до версии 11.0.2963.11001 файлы DCC32.exe и DCC100.dll. Если на форуме есть нежадные люди, не страдающие копирофилией, скиньте пожалуйста мне их на мыло (falsemaster@rambler.ru) или залейте на какой-нибудь обменник. Они в zip'е всего метр весят.
Автор: idiMAN
Дата сообщения: 17.08.2012 06:55
FalseMaster
Вот, лови...
Автор: FalseMaster
Дата сообщения: 17.08.2012 07:33
Извиняюсь за оффтопик, но если чё, модер пост может кильнуть. Просто хочу выразить благодарность. idiMAN, спасибо огромное, ты меня спас от нервного срыва - я уже третьи сутки тщетно прошу эти файлики на разных форумах - дохлый номер, никто не даёт. Видимо в рунете стало очень много уродов на квадратный сантиметр. ... В общем, спасибо ещё раз и всего наилучшего.
Автор: idiMAN
Дата сообщения: 17.08.2012 08:23
FalseMaster
Я думаю большинство просто сидит на старших версиях...
Автор: Frodo_Torbins
Дата сообщения: 17.08.2012 15:09
Maks150988
Ну если всегда копироватся должно, то там более менее нормально. А проверку SrcInfo.pszText добавьте рядом с DestInfo.pszText.
Автор: Maks150988
Дата сообщения: 17.08.2012 16:09
Frodo_Torbins


Код: function AllocArrayItem(var ptrInfo: MY_INFO_EX): Boolean;
begin
GetMem(ptrInfo.pszText, ptrInfo.cchTextMax);
Result := ptrInfo.pszText <> nil;
end;

procedure CopyArrayItem(var DestInfo: MY_INFO_EX; const SrcInfo: MY_INFO_EX);
var
bRet: Boolean;
begin
CopyMemory(@DestInfo, @SrcInfo, SizeOf(MY_INFO_EX));
if (SrcInfo.pszText <> nil) then
begin
bRet := AllocArrayItem(DestInfo);
if bRet then
lstrcpynW(DestInfo.pszText, SrcInfo.pszText, DestInfo.cchTextMax);
end;
end;
Автор: Frodo_Torbins
Дата сообщения: 17.08.2012 18:39
Maks150988
Вроде так. А в UpdateArrayItem у вас куча ненужных перераспределений памяти благодаря DeleteArrayItem и InsertArrayItem. От них нужно избавится.
Автор: Maks150988
Дата сообщения: 18.08.2012 08:17
Frodo_Torbins
А что вы можете предложить? Хотя бы подкиньте ссылочек на использование подобных массивов. А то вечно с ShortString хрень попадается.
Автор: A_V
Дата сообщения: 18.08.2012 12:51
Maks150988
UpdateArrayItem можно написать через:

FreeArrayItem(DynArray[idItemIndex]);
CopyArrayItem(tmpInfo, InfoEx);
DynArray[idItemIndex] := tmpInfo;
Автор: Maks150988
Дата сообщения: 18.08.2012 20:56
Frodo_Torbins
A_V

Да вот хотел на простом примере проконсультироваться тут. Не все так просто. Вот рекорд и функции из моего проекта.

[more=Дальше]




type
PACCOUNT_INFO_EX = ^ACCOUNT_INFO_EX;
ACCOUNT_INFO_EX = record
bUpdateState : Boolean;
clsid : TGUID;
dwEqualIndex : Integer;
pszAccount : LPWSTR;
cchAccountMax : Integer;
pszLogin : LPWSTR;
cchLoginMax : Integer;
pszPassword : LPWSTR;
cchPasswordMax : Integer;
fBalance : Double;
fOverdraft : Double;
pszTarif : LPWSTR;
cchTarifMax : Integer;
pszUpdated : LPWSTR;
cchUpdatedMax : Integer;
dwTarifDays : Integer;
dwTarifDaysLeft: Integer;
dwErrorCode : Integer;
pszError : LPWSTR;
cchErrorMax : Integer;
bYellowAlert : Boolean;
fYellowAlert : Double;
bRedAlert : Boolean;
fRedAlert : Double;
end;

type
TAccountInfoExArr = Array of ACCOUNT_INFO_EX;

//

procedure AllocDataItem(var ptrInfo: ACCOUNT_INFO_EX);
begin
GetMem(ptrInfo.pszAccount, ptrInfo.cchAccountMax);
GetMem(ptrInfo.pszLogin, ptrInfo.cchLoginMax);
GetMem(ptrInfo.pszPassword, ptrInfo.cchPasswordMax);
GetMem(ptrInfo.pszTarif, ptrInfo.cchTarifMax);
GetMem(ptrInfo.pszUpdated, ptrInfo.cchUpdatedMax);
GetMem(ptrInfo.pszError, ptrInfo.cchErrorMax);
end;

//

procedure FreeDataItem(var ptrInfo: ACCOUNT_INFO_EX);
begin
FreeMem(ptrInfo.pszAccount, ptrInfo.cchAccountMax);
FreeMem(ptrInfo.pszLogin, ptrInfo.cchLoginMax);
FreeMem(ptrInfo.pszPassword, ptrInfo.cchPasswordMax);
FreeMem(ptrInfo.pszTarif, ptrInfo.cchTarifMax);
FreeMem(ptrInfo.pszUpdated, ptrInfo.cchUpdatedMax);
FreeMem(ptrInfo.pszError, ptrInfo.cchErrorMax);
ptrInfo.pszAccount := nil;
ptrInfo.pszLogin := nil;
ptrInfo.pszPassword := nil;
ptrInfo.pszTarif := nil;
ptrInfo.pszUpdated := nil;
ptrInfo.pszError := nil;
end;

//

procedure CopyDataItem(var DestInfo: ACCOUNT_INFO_EX; const SrcInfo: ACCOUNT_INFO_EX);
begin
lstrcpynW(DestInfo.pszAccount, SrcInfo.pszAccount, DestInfo.cchAccountMax);
lstrcpynW(DestInfo.pszLogin, SrcInfo.pszLogin, DestInfo.cchLoginMax);
lstrcpynW(DestInfo.pszPassword, SrcInfo.pszPassword, DestInfo.cchPasswordMax);
lstrcpynW(DestInfo.pszTarif, SrcInfo.pszTarif, DestInfo.cchTarifMax);
lstrcpynW(DestInfo.pszUpdated, SrcInfo.pszUpdated, DestInfo.cchUpdatedMax);
lstrcpynW(DestInfo.pszError, SrcInfo.pszError, DestInfo.cchErrorMax);
end;

//

procedure CopyArrayItem(var DestInfo: ACCOUNT_INFO_EX; const SrcInfo: ACCOUNT_INFO_EX);
begin
CopyMemory(@DestInfo, @SrcInfo, SizeOf(ACCOUNT_INFO_EX));
AllocDataItem(DestInfo);
CopyDataItem(DestInfo, SrcInfo);
end;

//

function InsertArrayItem(var DynArray: TAccountInfoExArr; const IdItemIndex: Integer; InfoEx: ACCOUNT_INFO_EX): Integer;
var
IdItem: Integer;
iCount: Integer;
begin
iCount := Length(DynArray);
if (IdItemIndex = -1) and (iCount = 0) then
Result := 0
else
if (IdItemIndex = -1) and (iCount <> 0) then
Result := iCount
else
Result := IdItemIndex;
SetLength(DynArray, iCount + 1);
for IdItem := iCount downto (Result + 1) do
DynArray[IdItem] := DynArray[IdItem - 1];
CopyArrayItem(DynArray[Result], InfoEx);
end;

//

function DeleteArrayItem(var DynArray: TAccountInfoExArr; const IdItemIndex: Integer): Integer;
var
bRet : Boolean;
IdItem: Integer;
iCount: Integer;
begin
Result := -1;
bRet := (IdItemIndex >= Low(DynArray)) and (IdItemIndex <= High(DynArray));
if bRet then
begin
FreeDataItem(DynArray[IdItemIndex]);
iCount := Length(DynArray);
for IdItem := (IdItemIndex + 1) to (iCount - 1) do
DynArray[IdItem - 1] := DynArray[IdItem];
SetLength(DynArray, iCount - 1);
Result := Length(DynArray);
end;
end;

//

function UpdateArrayItem(var DynArray: TAccountInfoExArr; const IdItemIndex: Integer; InfoEx: ACCOUNT_INFO_EX): Boolean;
var
bRet : Boolean;
tmpInfo: ACCOUNT_INFO_EX;
IdItem : Integer;
begin
Result := FALSE;
bRet := (IdItemIndex >= Low(DynArray)) and (IdItemIndex <= High(DynArray));
if bRet then
begin
{
FreeDataItem( DynArray[IdItemIndex] );
CopyArrayItem( DynArray[IdItemIndex], InfoEx );
Result := True;
}
CopyArrayItem(tmpInfo, InfoEx);
DeleteArrayItem(DynArray, IdItemIndex);
IdItem := InsertArrayItem(DynArray, IdItemIndex, tmpInfo);
FreeDataItem(tmpInfo);
Result := IdItem <> -1;
end;
end;



[/more]

Функция UpdateArrayItem с закомментированным кодом не отрабатывает как положено. Почему-то в указателях появляется мусор в конце. Вот и удаляю я элемент в списке и заного его добавляю. Хочется просто тупо сделать аналог сообщения, например, LVM_INSERTITEM, где заполняем структуру и контрол сам копирует себе то что нужно и орудует выделенными буферами с текстом. А дальше я достаю инфу из этого массива и отображаю пользователю...
Автор: A_V
Дата сообщения: 19.08.2012 19:16
Maks150988

Цитата:
Почему-то в указателях появляется мусор в конце

значит где-то строка не завершается с #0#0. приведи полный пример с ошибкой.

вообще, если все это внутри твоего приложения, то чем дельфевые строки не устроили?
Автор: Maks150988
Дата сообщения: 19.08.2012 20:40
A_V
Строки Delphi не устроили тем, что впоследствии я расчитывал на использование плагинов, написанных на других языках. Приложение у меня поддерживает полностью Юникод, вроде как можно было напрямую WideString передавать, но я хотел еще сделать Ansi варинат для устаревших систем. Так что потом можно было легко поменять PWideChar на PAnsiChar.

Вобщем так, кода многовато, поехали... Будем считать, что у меня уже запущена программа и массив pAccountData (TAccountInfoExArr это Array of ACCOUNT_INFO_EX) заполнен необходимыми значениями. Для манипуляции с массивом используется тот код функций из предыдущего сообщения.

Для примера обновим 3 элемент массива значениями из структурки ptrInfo. Эту структуру заполняет функция UpdateItemInfo, в которую плагин передает некоторые значения. Если UpdateItemInfo вернула True, значит обновим столбцы и строки ListView и обновим элемент в массиве pAccountData.

var
bRet : Boolean;
ptrInfo : ACCOUNT_INFO_EX;
begin
bRet := UpdateItemInfo(3, ptrInfo);
if bRet then
begin
UpdateListItem(hListView, 3, ptrInfo);
UpdateArrayItem(pAccountData, 3, ptrInfo);
end;
end;


Сам код функции UpdateListItem приводить не буду полностью. Он грубо говоря примерно такой. Вобщем здесь ошибок уж точно не должно быть...

ZeroMemory(@lvi, SizeOf(TLVItemW));
lvi.mask := LVIF_TEXT;
lvi.iItem := nDestItem;
lvi.iSubItem := IdItem;
lvi.pszText := ptrInfo.pszAccount;
SendMessageW(hListView, LVM_SETITEMW, 0, Integer(@lvi));


Код функции UpdateArrayItem в предыдущем сообщении. Приведу лучше код функций UpdateItemInfo (заполняет инфой от плагина заветную структуру). Может и тут косячок...

function UpdateItemInfo(const IdItem: Integer; var ptrInfo: ACCOUNT_INFO_EX): Boolean;
var
dwInfoIndex: Integer;
ai : ACCOUNT_INFO;
exec : TPluginExecute;
st : TSystemTime;
pszText : WideString;
begin
Result := FALSE;
ZeroMemory(@ai, SizeOf(ACCOUNT_INFO));
ai.pszLogin := pAccountData[IdItem].pszLogin;
ai.pszPassword := pAccountData[IdItem].pszPassword;
ai.cchPasswordMax := pAccountData[IdItem].cchPasswordMax;
ai.fBalance := pAccountData[IdItem].fBalance;
ai.fOverdraft := pAccountData[IdItem].fOverdraft;
ai.pszTarif := pAccountData[IdItem].pszTarif;
ai.cchTarifMax := pAccountData[IdItem].cchTarifMax;
ai.dwTarifDays := pAccountData[IdItem].dwTarifDays;
ai.dwTarifDaysLeft := pAccountData[IdItem].dwTarifDaysLeft;
ai.dwErrorCode := pAccountData[IdItem].dwErrorCode;
ai.pszError := pAccountData[IdItem].pszError;
ai.cchErrorMax := pAccountData[IdItem].cchErrorMax;
dwInfoIndex := pAccountData[IdItem].dwEqualIndex;
if (dwInfoIndex <> -1) then
begin
exec := pPluginData[dwInfoIndex].exec;
Result := exec(ai);
end;
if Result then
begin
GetLocalTime(st);
pszText := FormatUpdateTimeDateW(st);
ptrInfo.bUpdateState := pAccountData[IdItem].bUpdateState;
ptrInfo.clsid := pAccountData[IdItem].clsid;
ptrInfo.dwEqualIndex := pAccountData[IdItem].dwEqualIndex;
ptrInfo.pszAccount := pAccountData[IdItem].pszAccount;
ptrInfo.cchAccountMax := pAccountData[IdItem].cchAccountMax;
ptrInfo.pszLogin := pAccountData[IdItem].pszLogin;
ptrInfo.cchLoginMax := pAccountData[IdItem].cchLoginMax;
ptrInfo.pszPassword := pAccountData[IdItem].pszPassword;
ptrInfo.cchPasswordMax := pAccountData[IdItem].cchPasswordMax;
ptrInfo.fBalance := ai.fBalance;
ptrInfo.fOverdraft := ai.fOverdraft;
ptrInfo.pszTarif := ai.pszTarif;
ptrInfo.cchTarifMax := ai.cchTarifMax;
ptrInfo.pszUpdated := LPWSTR(pszText);
ptrInfo.cchUpdatedMax := (lstrlenW(ptrInfo.pszUpdated) + 1) * SizeOf(WideChar);
ptrInfo.dwTarifDays := ai.dwTarifDays;
ptrInfo.dwTarifDaysLeft:= ai.dwTarifDaysLeft;
ptrInfo.dwErrorCode := ai.dwErrorCode;
ptrInfo.pszError := ai.pszError;
ptrInfo.cchErrorMax := ai.cchErrorMax;
ptrInfo.bYellowAlert := pAccountData[IdItem].bYellowAlert;
ptrInfo.fYellowAlert := pAccountData[IdItem].fYellowAlert;
ptrInfo.bRedAlert := pAccountData[IdItem].bRedAlert;
ptrInfo.fRedAlert := pAccountData[IdItem].fRedAlert;
end;
end;


Тут собственно просто. Заполняем структуру ACCOUNT_INFO (не ACCOUNT_INFO_EX!) данными из текущей ACCOUNT_INFO_EX (ну нужен логин и пароль просто) и подаем ее в функцию PluginExecute. Она выдает данные и мы присваиваем их в структуре ptrInfo.

Ну а вот и сама родимая PluginExecute из плагина...

function PluginExecute(out ai: ACCOUNT_INFO): BOOL; stdcall;
type
TBillingInfo = record
errorCode : Integer;
msgError : LPWSTR;
balanceMoney: Double;
balanceDraft: Double;
tarifName : LPWSTR;
tarifDays : Integer;
daysLeft : Integer;
end;
const
pszTarif: LPWSTR = 'Обычный тарифный план';
pszError: LPWSTR = 'Ошибок не обнаружено';
var
binfo: TBillingInfo;
begin
ZeroMemory(@binfo, SizeOf(TBillingInfo));
binfo.errorCode := NO_ERROR;
binfo.msgError := pszError;
binfo.balanceMoney:= 250.00;
binfo.balanceDraft:= 30.00;
binfo.tarifName := pszTarif;
binfo.tarifDays := -1;
binfo.daysLeft := -1;
ai.fBalance := binfo.balanceMoney;
ai.fOverdraft := binfo.balanceDraft;
ai.pszTarif := binfo.tarifName;
ai.cchTarifMax := (lstrlenW(ai.pszTarif) + 1) * SizeOf(WideChar);
ai.dwTarifDays := binfo.tarifDays;
ai.dwTarifDaysLeft := binfo.daysLeft;
ai.dwErrorCode := binfo.errorCode;
ai.pszError := binfo.msgError;
ai.cchErrorMax := (lstrlenW(ai.pszError) + 1) * SizeOf(WideChar);
Result := TRUE;
end;


Вобщем-то у меня попутно вопрос. Может теряются указатели после UpdateListItem перед UpdateArrayItem? Или данные в ptrInfo становятся невалидными...
Автор: A_V
Дата сообщения: 19.08.2012 22:57
Maks150988
для того, чтобы быстро найти, почему 'в указателях появляется мусор в конце', нужен минимальный компилируемый код, воспроизводящий ошибку. собирать его из разных кусков, дописав еще часть самостоятельно у меня желания нет.

но, из того, что ты приводишь,

Цитата:
ptrInfo.pszPassword := pAccountData[IdItem].pszPassword;

не удивительно, что потом вылезают проблемы.. ты уверен, что нужно копировать указатели, а не строки?

еще,

Цитата:
ai.cchTarifMax := (lstrlenW(ai.pszTarif) + 1) * SizeOf(WideChar)

если это потом используется для работы с юникдными api-ф-иями, умножать на 2 не нужно.
Автор: Frodo_Torbins
Дата сообщения: 20.08.2012 11:45

Цитата:
Строки Delphi не устроили тем, что впоследствии я рассчитывал на использование плагинов, написанных на других языках. Приложение у меня поддерживает полностью Юникод, вроде как можно было напрямую WideString передавать, но я хотел еще сделать Ansi вариант для устаревших систем. Так что потом можно было легко поменять PWideChar на PAnsiChar.
Чтобы легко прекомпилировать в анси вариант, нужно было свой тип вводить наподобие такого "type MyChar = WideChar;" и уже далее всюду его использовать. Но вообще реальная польза от всей этой возни с указателями весьма сомнительна. Я бы избавлялся от них как только данные поступили от плагина (в UpdateItemInfo). И внутри уже всюду использовал бы нормальные строки. Или вообще забил на анси версию, и повсеместно использовал бы WideString.
Автор: Maks150988
Дата сообщения: 21.08.2012 08:20

Цитата:
не удивительно, что потом вылезают проблемы.. ты уверен, что нужно копировать указатели, а не строки?

Да я вот только сейчас понял про присваивание указателей. Почему-то казалось что после заполнения ptrInfo текст сохранится. А тут получается я уже обновляю текущий элемент массива из которого я текст "сохранял".


Цитата:
если это потом используется для работы с юникдными api-ф-иями, умножать на 2 не нужно.

Почему не нужно?


Цитата:
Я бы избавлялся от них как только данные поступили от плагина (в UpdateItemInfo)

Каким образом?
Автор: A_V
Дата сообщения: 21.08.2012 09:18
Maks150988

Цитата:
Почему не нужно?

Потому что обычно ф-ии (lstrcpyn) принимают кол-во символов, а не размер в байтах

Цитата:
Цитата:
Я бы избавлялся от них как только данные поступили от плагина (в UpdateItemInfo)

Каким образом?

перегонять все в widestring видимо
Автор: Ichigo2
Дата сообщения: 21.08.2012 09:18
Опять приветик.
Вкратце суть такова - моя программа загружает фотки в Timage, что не совсем быстро. А в каждом каталоге с фотками в системе есть файл Thumbs.db c эскизами. Можно ли из этого файлика загрузить в TImage миниатюры текущей директории и как?
Автор: A_V
Дата сообщения: 21.08.2012 09:39
Ichigo2
Тынц
Тынц
Автор: Ichigo2
Дата сообщения: 21.08.2012 09:43
A_V
О спасибо, а то дальше википедии я не ушел
Автор: Aleksandr N
Дата сообщения: 21.08.2012 18:29
Подскажите по WinAPI
Есть часть функции:

DeskDC := GetDC(h_Wnd);
hBmp := CreateCompatibleBitmap(DeskDC, ScrX, ScrY);
DC := CreateCompatibleDC(DeskDC);
SelectObject(DC, hbmp);
BitBlt(DC, 0, 0, SCRX, SCRY, DeskDC, 0, 0, SrcCopy);

Этот код создаёт картинку чужого контрола вместе с контролами, лежащими на нём. Например, если создавать картинку трея, то создаётся картинка вместе с иконками и часами.
Как создать картинку БЕЗ поверх лежащих контролов?
Автор: A_V
Дата сообщения: 21.08.2012 21:49
Aleksandr N
Для конкретно указанного окна - PrintWindow.
Или ты хочешь, что-бы _дочерние_ контролы не отрисовались?
Автор: Aleksandr N
Дата сообщения: 21.08.2012 22:06
A_V
Да, именно чтобы дочерние не отрисовались. PrintWindow пробывал, рисует всё как видишь.

ИЛИ
Поставим задачу иначе. Есть ещё часть функции

hControlDC := BeginPaint(h_Wnd, PS);
if hControlDC <> 0 then
begin
try
iSavedID := SaveDC(hControlDC);
SetWindowOrgEx(hControlDC, DeltaPosX, GetWindowSize(hNotifyWnd) - GetWindowSize(h_Wnd), nil);
CallWindowProc(OldNotifyWndProc, hNotifyWnd, WM_PRINTCLIENT, hControlDC, PRF_CLIENT or PRF_ERASEBKGND);
RestoreDC(hControlDC, iSavedID);
finally
EndPaint(h_Wnd, PS);
end;

она нормально рисует фон на нужном мне контроле. Но я не представляю как сюда вставить часть кода "забирающего" то что нарисовалось на нужном контроле (фон). Для примера опять тот-же трей, когда на окне часов рисуется фон за часами (текущее время, естественно, не видно что и требуется). Вот в это время нужно забрать то, что нарисовалось на часах.

Страницы: 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374

Предыдущая тема: MPO File


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.