Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "KOL";
Текущий архив: 2010.02.14;
Скачать: [xml.tar.bz2];

Вниз

Вопросы к Старшим   Найти похожие ветки 

 
MYRX   (2008-04-17 10:56) [0]

Добрый день, уважаемые мастера. Взялся я писать куросовой на KOL
хочется написать простенький редактор pas-файлов

Задумка:
возможность открывать несколько файлов на разных вкладках
для этого сделал отдельный фрейм с редактром кода
и создаю его на каждой вкладке так:


procedure CreateEmptyTab(Str:String);
var tmp:PfrEditor;
begin
 if not Assigned(FrameList) then
   FrameList:=NewList;
 if not Assigned(PathList) then
   PathList:=NewStrList;
 fmMan.TCMain.TC_Insert(fmMan.TCMain.Count,"",0);
 fmMan.TCMain.CurIndex:=fmMan.TCMain.Count-1;
 fmMan.TCMain.TC_Items[fmMan.TCMain.CurIndex]:=Str;
 NewfrEditor(tmp,fmMan.TCMain.Pages[fmMan.TCMain.CurIndex]);
 FrameList.Add(tmp);
 PfrEditor(FrameList.Item[fmMan.TCMain.CurIndex]).MEPas.Focused:=True;
 PathList.Add("");
end;


В PathList храню пути до файлов, открытых на вкладках или пустую строку, если вкладка пустая
в FrameList хранятся указатели на созданные фреймы
MEPas - это memo на фрейме

вопрос заключается в следующем:
как мою задумку организовать правильно

а еще как все это правильно уничтожить при закрытии вкладки
подскажите плиззз


 
Danger ©   (2008-04-17 12:59) [1]

Можно оформить это все в отдельный объект (скажем, TEditor), членами которого являются memo и прочие контролы на вкладке. Указатели на экземпляры TEditor хранить в глобальном динамическом массиве: TEditors = array of TEditor;

При создании вкладки динамически создаем объект (в конструкторе объекта будет инициализироваться memo и прочие контролы), и добавляем указатель на объект TEditor в массив, для последующих обращений к объекту и его дочерним объектам (memo, например).

При закрытии вклядки уничтожать объект TEditor и его дочерние объеты. Удаляем из массива указатель на объект (если надо, сдвигаем элементы к началу массива и устанавливаем новую длину массива).

Обращаться к memo, расположенным на разных вкладках легко, т.к. номер вкладки будет совпадать с индексом экземпляра TEditor в массиве. Т.е., чтобы обратиться к свойству Text у memo, расположенному на третьей вкладке, делаем примерно TEditors[2].Memo.Text:= "blablabla";

Дополнительно, для удобства можно ввести в объект TEditor методы, например TEditor.LoadFile(), TEditor.SaveFile(), TEditor.CopyToInternalClipboard() и. т.п. В общем, в такой схеме можно всегда обратиться к любому контролу на любой вкладке, и упростить работу с блоком контролов на вкладке, управлять созданием/уничтожением целых блоков контролов при необходимости.


 
Danger ©   (2008-04-17 13:05) [2]

А в качестве memo, кроме обычного memo, можно использовать RichEdit; KOLHilightMemo Владимира Кладова; или VMHSyntaxEdit, VMHPasHighlighter (последние, впрочем, глючат неслабо).


 
MYRX   (2008-04-17 13:41) [3]

Спасибо, Danger, направление мысли понял. Если не трудно приведи примерчик для тех, кто в танке. Признаюсь честно: я - в бронепоезде


 
Дмитрий К ©   (2008-04-17 13:58) [4]

А можно, например, так: один memo и панелька с кнопочками.  К каждой кнопочке привязан объект в котором хранятся путь файла, изменения в файле, еще какая-нибудь лабуда. При создании кнопочки объект создается, инициализируются его поля. При разрушении соответственно все уничтожается.
Для кнопочек можно использовать тот же TabControl, только его "кнопочную" часть, скрыв под memo все остальное.


 
MYRX   (2008-04-17 14:15) [5]

Спасибо за совет, Дмитрий.
Все-таки я предпочту "Вкладочный" вариант.
Только есть одна просьбочка ко всем мастерам.
Я не представляю, как динамически создавать объект, состоящий из кучи других объектов, да еще как-то это все закинуть на вкладку, может кто-нить поделится, хоть приблизительным описанием подобного объекта на языке Паскаль и кодом его инициализации и уничтожения?


 
Danger ©   (2008-04-17 15:16) [6]


> MYRX   (17.04.08 13:41) [3]
> Если не трудно, приведи примерчик для тех, кто в танке.
> Признаюсь честно: я - в бронепоезде

Попозже кину пример создания объекта, в данный момент немного занят ...


> Я не представляю, как динамически создавать объект, состоящий
> из кучи других объектов, да еще как-то это все закинуть
> на вкладку, может кто-нить поделится, хоть приблизительным
> описанием подобного объекта на языке Паскаль и кодом его
> инициализации и уничтожения?

Точно так же, как динамически создается любой другой объект (форму, кнопку и т.п.).


 
Barloggg   (2008-04-17 15:36) [7]

> MYRX   (17.04.08 13:41) [3]
покури пример с Frame

создаешь два проекта. или лучше просто две формы
первый твой таб с вкладками и делается как обычно
второй это конкретно одна вкладка со всем что тебе на ней нужно. только вместо КолФорм надо бросить туда КолФраме.

убрать вторую форму из списка автосоздаваемых.
а потом нужное тебе количество вкладок клонировать как сказал Danger [1]


 
MYRX   (2008-04-17 19:35) [8]

Спасибо всем за содействие
2 Danger если на форум влом скидывать пример, то скинь, пожалуйста на
myrx@inbox.ru


 
Danger ©   (2008-04-18 10:28) [9]


> MYRX   (17.04.08 19:35) [8]

Вот простой пример набросал: http://alhoster.com/TabEditExample.7z
Буду рад, если поможет.


 
MYRX   (2008-04-18 15:55) [10]

Спасибо огоромное!

пример вывел меня из тупика
теперь могу писать курсовой дальше


 
MYRX   (2008-04-18 16:07) [11]

Появился еще один вопрос к мастерам

хочется сделать красивый About, на основе картинки jpg
но вот незадача, как в программу "запихнуть" эту картинку

логично использовать ресурсы

Сложность-же заключается в том, как из этих ресурсов
взять эту картинку, декодировать и нарисовать на канвасе
формы, не создавая промежуточного файла.

Снова надеюсь старших товарищей
Может кто-нить подкинет кода кусочек?


 
Compiler ©   (2008-04-18 22:16) [12]

Для работы с jpeg и gif я использую юнит tinyJPGGIFBM от homm, который входит в состав GrushControls
Вот примерчик:

var
 B:PBitmap;
...  
b:=NewBitmap(0,0);
tinyLoadJPGGIFBMPResource(b,hinstance,"Splash","Splash");
b.Draw(Form.canvas.handle,0,0);
...
B.Free;


 
MYRX   (2008-04-19 01:57) [13]

Быстро, посто и удобно!
Все работает
Спасибо, Compiler!


 
MYRX   (2008-04-21 02:41) [14]

Снова я)
Запостю весь топик глупыми вопросами,
но что делать?

Если нет своего ума - одолжи у другого.

Возник вопрос такой:
хочу в этом редакторе подсветку синтаксиса сделать на базе KOLHilightEdit
очень шустрый, маленький и функциональный компонент, (респект Кладову)
но вот беда, не получается у меня пользоваться его функционалом
ключевые слова кое-как подсвечиваю


function TEditor.HilightPAS(Sender: PControl; const FromPos: TPoint; var Attrs: TTokenAttrs): Integer;
...
begin
 S := fHEdit.Edit.Lines[ FromPos.Y ];
 Result := 0;
 if S = "" then
 begin
 i := FromPos.X;
 isReserved := FALSE;
...
    if not fStr and
      ((AnsiCompareStrNoCase( Copy( S, i+1, 5 ), "begin" ) = 0) or
      (AnsiCompareStrNoCase( Copy( S, i+1, 3 ), "end" ) = 0) or
      (AnsiCompareStrNoCase( Copy( S, i+1, 3 ), "var" ) = 0) or
      (AnsiCompareStrNoCase( Copy( S, i+1, 5 ), "const" ) = 0) or
      (AnsiCompareStrNoCase( Copy( S, i+1, 2 ), "or" ) = 0) or
      (AnsiCompareStrNoCase( Copy( S, i+1, 2 ), "if" ) = 0) or
      (AnsiCompareStrNoCase( Copy( S, i+1, 4 ), "then" ) = 0) or
      (AnsiCompareStrNoCase( Copy( S, i+1, 3 ), "for" ) = 0) or
      (AnsiCompareStrNoCase( Copy( S, i+1, 5 ), "while" ) = 0) or
      (AnsiCompareStrNoCase( Copy( S, i+1, 2 ), "do" ) = 0) or
      (AnsiCompareStrNoCase( Copy( S, i+1, 8 ), "function" ) = 0) or
      (AnsiCompareStrNoCase( Copy( S, i+1, 9 ), "procedure" ) = 0) or
      (AnsiCompareStrNoCase( Copy( S, i+1, 14 ), "implementation" ) = 0) or
      (AnsiCompareStrNoCase( Copy( S, i+1, 5 ), "array" ) = 0) or
      (AnsiCompareStrNoCase( Copy( S, i+1, 11 ), "constructor" ) = 0) or
      (AnsiCompareStrNoCase( Copy( S, i+1, 8 ), "property" ) = 0) or
      (AnsiCompareStrNoCase( Copy( S, i+1, 4 ), "type" ) = 0) or
      (AnsiCompareStrNoCase( Copy( S, i+1, 10 ), "destructor" ) = 0) or
      (AnsiCompareStrNoCase( Copy( S, i+1, 4 ), "uses" ) = 0) or
      (AnsiCompareStrNoCase( Copy( S, i+1, 9 ), "interface" ) = 0) or
      (AnsiCompareStrNoCase( Copy( S, i+1, 7 ), "program" ) = 0) or
      (AnsiCompareStrNoCase( Copy( S, i+1, 2 ), "in" ) = 0) or
      (AnsiCompareStrNoCase( Copy( S, i+1, 4 ), "object" ) = 0)
                                                ...                           ) then
    begin
      isReserved := TRUE;
          if S[ i+1 ] <= " " then
           while (i < Length( S )) and (S[ i+1 ] <= " ") and ( not (S[ i+1 ] in delims)) and (S[i+1]<>#39)  do inc( i )
          else
           while (i < Length( S )) and (S[ i+1 ] > " ") and ( not (S[ i+1 ] in delims)) and (S[i+1]<>#39) do inc( i );
    end
...
 Result := i - FromPos.x;
 if isReserved then
 begin
   Attrs.fontstyle := [ fsBold ];
   Attrs.fontcolor := 16776960;
   Attrs.backcolor := clBlack;
 end
...
 begin
   Attrs.FontStyle := [ ];
   Attrs.fontcolor := clWhite;
   Attrs.backcolor := clBlack;
 end;
end;


А вот как подсветить строковые параметры (те, что в кавычках)? - ума не приложу

до 3-х часов ночи бился, так и не победил
поделитесь, кто-нить опытом, если не жалко...

P.S.
Пробовал использовать PVMHSyntaxEdit + PVMHPasHighlighter
программа увеличилась вдвое ((


 
Danger ©   (2008-04-21 11:07) [15]


> P.S.
> Пробовал использовать PVMHSyntaxEdit + PVMHPasHighlighter
> программа увеличилась вдвое ((

Ладно бы размер, но к сожалению там есть глюки в самом редакторе - к примеру, помню, что не удавалось перетащить выделенный блок текста в редакторе (хотя оригинальный TSynEdit позволял так делать).


 
mdw ©   (2008-04-21 11:41) [16]

У меня примерно так. Правда многострочные коментарии так и не доделал.

type TTokens = (tNone, tReservedWord, tComment, tCharStr, tDigital);
const ReservedWordsCount = 72;
     ReservedWords: array [0..ReservedWordsCount-1]of string = (
                                              "and", "array", "as", "asm",
                                              "begin", "case", "class", "const",
                                              "constructor", "destructor", "dispinterface", "div",
                                              "do", "downto", "else", "end",
                                              "except", "exports", "file", "finalization",
                                              "finally", "for", "function", "goto",
                                              "if", "implementation", "in", "inherited",
                                              "initialization", "inline", "interface", "is",
                                              "label", "library", "mod", "nil",
                                              "not", "object", "of", "or",
                                              "out", "packed", "procedure", "program",
                                              "property", "raise", "record", "repeat",
                                              "resourcestring", "set", "shl", "shr",
                                              "string", "then", "threadvar", "to",
                                              "try", "type", "unit", "until",
                                              "uses", "var", "while", "with",
                                              "xor", "private", "protected", "public",
                                              "published", "automated", "at", "on"
                                              );

procedure TCodesForm.KOLMDIChildFormCreate(Sender: PObj);
var i: Integer;
   Item: THandle;
begin
   FReservedWords:= NewStrList;
   for i:= 0 to ReservedWordsCount-1 do ReservedWords.Add(ReservedWords[i]);
   FReservedWords.Sort(False);
end;

function TCodesForm.HEditScanToken(Sender: PControl; const FromPos: TPoint; var Attrs: TTokenAttrs): Integer;
begin
    Attrs.fontcolor := clWindowText;
    Attrs.fontstyle := [ ];
    case ParseLine(HEdit.Edit.Lines[FromPos.Y], FromPos.X+1, Result) of
      tReservedWord: Attrs.fontstyle:= [fsBold];
      tComment: begin
        Attrs.fontstyle:= [fsItalic];
        Attrs.fontcolor:= clGrayText;
      end;
      tCharStr: begin
        Attrs.fontstyle:= [];
        Attrs.fontcolor:= clFuchsia;
      end;
      tDigital: begin
        Attrs.fontstyle:= [];
        Attrs.fontcolor:= clBlue;
      end;
    end
end;

const Separators = " ;.,:=><()[]*+-/@^&#${}";

// {}  (* *)
function TCodesForm.ParseLine(ASource: String; APos: Integer; var ALength: Integer): TTokens;
var k: Integer;
   S: String;
begin
   Result:= tNone;
   ALength:= 1;
   ASource:= AnsiLowerCase(ASource);
   Delete(ASource, 1, APos-1);
   if ASource = "" then Exit;

   //Коментарии
   if Copy(ASource, 1, 2) = "//" then begin
     ALength:= Length(ASource);
     Result:= tComment;
     Exit;
   end;
   if (ASource[1] = "{") then begin
     ALength:= Pos("}", ASource);
     if ALength = 0 then ALength:= Length(ASource);
     Result:= tComment;
     Exit;
   end;

   //Строки
   if ASource[1] = """" then begin
     Delete(ASource, 1, 1);
     k:= Pos("""", ASource);
     if k = 0 then k:= Length(ASource);
     ALength:= k+1;
     Result:= tCharStr;
     Exit;
   end;
   if ASource[1] = "#" then begin
     ALength:= 1;
     while (Length(ASource)>ALength)and(ASource[ALength+1] in ["#", "0".."9"]) do inc(ALength);
     Result:= tCharStr;
     Exit;
   end;

   //Цифры
   if ASource[1] in ["$", "0".."9"] then begin
     ALength:= 1;
     while (Length(ASource)>ALength)and
           ((ASource[ALength+1] in [".", "0".."9"])or
            ((ASource[1]="$")and(ASource[ALength+1] in ["a".."f"]))) do inc(ALength);
     Result:= tDigital;
     Exit;
   end;

   S:= Parse(ASource, Separators);
   if FReservedWords.Find(S, k) then Result:= tReservedWord;
   ALength:= Max(1, Length(S));
end;


 
MYRX   (2008-04-21 17:06) [17]

Спасибо, mdw!
сегодня ночью попробую.

Вот только не понимая что к чему трудно пользоваться, а тем более дорабатывать

Я так и не могу понять:
1) что мы должны вернуть в резалте HEditScanToken,
   т.е. что означает возвращаемое нами число?

2)Что вообще означает "Токен"? (просто если пойму, то наверное будет попроще)


 
mdw ©   (2008-04-21 19:11) [18]


> 2)Что вообще означает "Токен"? (просто если пойму, то наверное
> будет попроще)

token  
1) знак
2) примета, признак


> 1) что мы должны вернуть в резалте HEditScanToken,    т.
> е. что означает возвращаемое нами число?

Открываем KOLHilightEdit.pas и читаем:

 TOnScanToken = function( Sender: PControl; const FromPos: TPoint;
                          var Attrs: TTokenAttrs ): Integer of object;
 { Методика подцветки синтаксиса такова: устанавливается обработчик события
   OnScanToken, который по необходимости получает координату FromPos, берет
   строку Lines[ FromPos.Y ], и с позиции FromPos.X (считается с нуля)
   определяет атрибуты токена (записывает их в Attrs), и возвращает длину токена.
   Не надо делать никакого компонента, если без него можно обойтись. }

Короче, вернуть должны длину строки, для которой устанавливаем атрибуты Attrs, в следующий раз OnScanToken будет вызываться уже со сдвигом на эту длину.


 
MYRX   (2008-04-21 20:05) [19]

Спасибо.
Теперь все встало на свои места.


 
=BuckLr= ©   (2008-04-22 11:02) [20]

По ходу обсуждения. А возможно ли реализовать компонент, аналогичный этому, только на основе richedit? Любопытно, но я никогда не видел подобной реализации.


 
mdw ©   (2008-04-22 11:51) [21]

У тедди на сайте есть нечто подобное, но довольно глючно работает. Я вообще на основе richedit не одной работоспособной реализации не видел.


 
=BuckLr= ©   (2008-04-22 13:20) [22]

У Thaddy? Это где? Я не видел... Было бы интересно посмотреть. Просто я видел на wasm.ru статью о реализации подсветки на основе richedit, но на asm-е. Думаеццо, раз можно на asm-t, то можно и на delphi :)


 
mdw ©   (2008-04-22 13:24) [23]

www.thaddy.com


 
=BuckLr= ©   (2008-04-22 15:12) [24]


> www.thaddy.com

Да я понял. Только нету там такого компонента :) Если есть у тебя, можешь скинуть?


 
mdw ©   (2008-04-22 19:17) [25]

http://thaddy.co.uk/koltomdemo.zip


 
MYRX   (2008-04-30 10:51) [26]

Еще один, наверное простой, вопрос:
Как сделать так, чтобы вкладка в TabControl выделялась по правому щелчку мыши(я подвязал к нему popup менюшку, вот и хочется, чтобы popup срабатывал для той вкладки, по которой был сделан правый клик)


 
Дмитрий К ©   (2008-04-30 14:46) [27]

Индекс вкладки над которой находится курсор можно узнать вот так:
function TabUnderCursorIndex: Integer;
var p: TPoint; r: TRect;
begin
 GetCursorPos(p);
 GetWindowRect(Tabs.Handle, r);
 Result := Tabs.TC_TabAtPos(p.X - r.Left, p.Y - r.Top);
end;


 
MYRX   (2008-05-03 14:21) [28]

Спасибо, Дмитрий!
Программа стла гораздо симпатичней.


 
MYRX   (2008-05-03 14:24) [29]

А кто - нить знает, как к popup привязать иконки (чтобы слева от пунктов отображались) и как в main-меню такое-же сотворить?


 
Danger ©   (2008-05-03 20:57) [30]


> А кто - нить знает, как к popup привязать иконки (чтобы
> слева от пунктов отображались) и как в main-меню такое-же
> сотворить?


В design-time свойства bitmap* элементов меню. Независимо от типа меню (main/popup).


 
MYRX   (2008-05-07 09:54) [31]

Снова выручаешь, Danger, спасибо!

Остался еще вопрос:

У меня в ImageList иконки хранятся 48х48

а как их уменьшить?
а то у меня в менюшках только краешки этих иконок рисуются...


 
Demt   (2008-05-07 19:13) [32]

MYRX, уменьшать надо графическим редактором, либо редактором иконок.


 
Danger ©   (2008-05-08 06:13) [33]


> Demt   (07.05.08 19:13) [32]
> MYRX, уменьшать надо графическим редактором, либо редактором
> иконок.


Или сразу грузить иконки подходящего размера (16х16). Обычно иконки (ICO) содержат в себе изображения разных размеров, скорее всего будут содержать и маленький значок. Можно выдрать его из коллекции и грузить только его в ImageList.

А если неохота заморачиваться, можно в нете поискать готовые наборы значков нужного размера, их там на любой вкус и цвет...


 
MYRX   (2008-05-08 09:38) [34]

Очень хочется позаморачивться )
у Битмапа есть же StretchDraw
Может можно это как-то использовать?
Просто неохота разбабахивать (увеличивать размер)
программу еще и уменьшенными копиями
уже имеющихся иконок

Нет ничего невозможного
Наверняка - же существует способ решить и эту проблему
Только я сам не додумаюсь,
потому и уповаю на более опытных товарищей


 
Danger ©   (2008-05-08 11:01) [35]


> MYRX   (08.05.08 09:38) [34]
> Просто неохота разбабахивать (увеличивать размер)
> программу еще и уменьшенными копиями
> уже имеющихся иконок
>


Если есть ICO-файл с нужной коллекцией значков, открываете его в редакторе иконок, и экспортируете из всего набора только маленькую иконку. Потом в вашей программе ставите  размер значков в ImageList"e 16х16, и добавляете туда ваш значок, вот и все. А большие значки из коллекции (32х32, 48х48) нет нужды таскать за собой, если они реально не будут использоваться.

Аналогично, если требуется размер 32х32 - ставите соответствующий размер в ImageList"e и добавляете в него только значок размером 32х32, выдранный из ICO-файла.


 
Compiler ©   (2008-05-08 14:14) [36]

> Очень хочется позаморачивться )

Сколько угодно. ;)

procedure BitmapCopyRect(OutBmp:HBITMAP; const OutRect: TRect; InBmp: HBITMAP;
 const InRect: TRect);
var InDC, OutDC: HDC;
   OldInDC, OldOutDC: THandle;
begin
 if (OutBmp = 0) or (InBmp = 0) or
    (OutBmp =InBmp) then Exit;
 InDC := CreateCompatibleDC( 0 );
 OldInDC := SelectObject( InDC, InBmp );
 OutDC := CreateCompatibleDC( 0 );
 OldOutDC := SelectObject( OutDC, OutBmp );
 StretchBlt( OutDC, OutRect.Left, OutRect.Top, OutRect.Right - OutRect.Left,
             OutRect.Bottom - OutRect.Top, InDC, InRect.Left, InRect.Top,
             InRect.Right - InRect.Left, InRect.Bottom - InRect.Top,
              SRCCOPY );
 SelectObject( OutDC, OldOutDC );
 DeleteDC( OutDC );
 SelectObject( InDC, OldInDC );
 DeleteDC( InDC );
end;

var  IL: pImageList;
procedure TForm1.KOLFormFormCreate(Sender: PObj);
var
Ob,InB:PBitmap;
begin
inb:=NewBitmap(0,0); //Рисунок из ресурса Высота 22 Ширина 216
Ob:=NewBitmap(144,16);  //Уменьшенный рисунок
InB.LoadFromResourceName(hinstance,"MAIN");
BitmapCopyRect(OB.Handle,MakeRect(0,0,Ob.Width,Ob.Height),
      InB.Handle,MakeRect(0,0,InB.Width,InB.Height));
IL := NewImageList( Form );
IL.Colors := ilcColorDDB;
IL.ImgWidth := 16;
IL.ImgHeight := 16;
IL.AddMasked(Ob.Handle,ClWhite);
InB.Free;
Ob.Free;


 
MYRX   (2008-05-14 13:40) [37]

Супер!
Спасибо, Compiler.
Работает гораздо лучше моего алгоритма
вот что значит опыт.
При большом количестве иконок выигрыш на лицо.


 
MYRX   (2008-05-14 13:45) [38]

По ходу назрело еще два вопроса:

1) Кто-нибудь знает, как расширить сами пункты меню, чтобы в них влезали большие иконки? (большие - красивше смотрятся)

2) И еще просьбочка:
  Поделитесь, пожалуйста, алгоритмом для анализа pas-файлов
  очень нужно определить уровень вложенности циклов.


 
Compiler ©   (2008-05-15 00:21) [39]

> 1) Кто-нибудь знает, как расширить сами пункты меню, чтобы
> в них влезали большие иконки? (большие - красивше смотрятся)

Изврат конечно, но для решения некоторвх задач подойдет
const
 mItemHeight=30;
 mItemWidth=100;

procedure DrawBitmap(DC: HDC;R:TRect;Bitmap:HBITMAP);
var
 DCfrom, DC0: HDC;
 oldBmp: HBitmap;
 B: TagBitmap;
begin
if Bitmap <> 0 then
 begin
   if GetObject( Bitmap, sizeof( B ), @B ) <> 0 then
   begin
   DC0 := GetDC( 0 );
   DCfrom := CreateCompatibleDC( DC0 );
   ReleaseDC( 0, DC0 );
   oldBmp := SelectObject( DCfrom, Bitmap );
   BitBlt( DC, R.Left+1,
           R.Top+(((R.Bottom- R.Top)-B.bmHeight) div 2),
           B.bmWidth, B.bmHeight,
           DCfrom, 0, 0, SRCCOPY );
   SelectObject( DCfrom, oldBmp );
   DeleteDC( DCfrom );
  end;
 end;
end;

function TForm1.MainMenu1DrawItem(Sender: PObj; DC: HDC; const Rect: TRect;
 ItemIdx: Integer; DrawAction: TDrawAction;
 ItemState: TDrawState): Boolean;
var
r:TRect;
begin
if (ItemIdx>=0) then begin
  R:=Rect;
  Inc(R.Left,40);
  FillRect(DC,Rect,GetSysColorBrush(COLOR_MENU));
  if PMenu(Sender).ItemEnabled[ItemIdx] then
  begin
  if odsSelected in  ItemState then
     FillRect(DC,Rect,GetSysColorBrush(COLOR_BTNFACE));
     SetTextColor(DC,ClBlack);
  end else begin
    SetTextColor(DC,ClGrey);
  end;
  SetBkMode(DC,TRANSPARENT);
  DrawBitmap(DC,Rect,PMenu(Sender).ItemBitmap[ItemIdx]);
  // или DrawIconEx(DC, Rect.Left,Rect.Top, LoadIcon(0,IDI_HAND),30,30, 0, 0, DI_NORMAL );
  DrawText(DC, Pchar(PMenu(Sender).ItemText[ItemIdx]),Length(PMenu(Sender).ItemText[ItemIdx]),
               R,DT_SINGLELINE or DT_VCENTER or DT_NOPREFIX);
  end;
end;

function TForm1.KOLForm1Message(var Msg: tagMSG;
 var Rslt: Integer): Boolean;
var MIS: PMeasureItemStruct;
begin
 Result := FALSE;
 case Msg.message of
  WM_MEASUREITEM : begin
   MIS := Pointer(msg.lParam);
   with MIS^ do begin
    begin
       itemHeight := mItemHeight;
       ItemWidth:=mItemWidth;
       Result := True;
       end;
       end;
      end;
  end;
end;

Еще можно использовать XPMenus, там можно задавать высоту и ширину меню не используя OnDrawItem, да и выглядит он лучше


 
Compiler ©   (2008-05-15 00:22) [40]

> Compiler ©   (15.05.08 00:21) [39]

OwnerDraw:=True; У каждого итема меню



Страницы: 1 2 вся ветка

Форум: "KOL";
Текущий архив: 2010.02.14;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.59 MB
Время: 0.006 c
1-1222968605
wipr
2008-10-02 21:30
2010.02.14
подскажите как работать с автоматизацией OpenOffice


4-1228932250
alextim
2008-12-10 21:04
2010.02.14
Ошибки страницы


2-1260637936
recop
2009-12-12 20:12
2010.02.14
После выполнения файла cmd получить содержание переменных среды


2-1260646194
BenderAnt
2009-12-12 22:29
2010.02.14
TelnetServer


2-1260663047
inkakas
2009-12-13 03:10
2010.02.14
использование png и canvas





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский