Źle dopasowane elementy w oknie programu - Windows Vista i 7

Źle dopasowane elementy w oknie programu - Windows Vista i 7
KA
  • Rejestracja:prawie 15 lat
  • Ostatnio:około 12 lat
0

Otóż mam taki problem. Piszę program, który jest swojego rodzaju edytorem. Chodzi o to, że w systemie Windows XP i starszych okno programu wygląda dobrze. Niestety w systemach Windows generacji 6, czyli Vista i 7 pojawia się taki problem:
user image
Po prostu ucina mi kilka pikseli z prawej strony. Napisałem nawet funkcję, która wykrywa rodzaj systemu operacyjnego i gdy wykryje Vistę lub 7-kę to program zmienia położenie przycisków troszkę w lewo i szerokość valuelisteditora. Niestety chciałem zaznaczyć, że po zmianie kompozycji na tą z Xp lub z 98 pozostaje mała szparka z prawej strony programu. Macie jakieś propozycje? Dodam tylko, że program ma na sztywno przypisany minimalny rozmiar okna i używam kompilatora Delphi 2007.

cimak
  • Rejestracja:ponad 22 lata
  • Ostatnio:ponad 9 lat
  • Postów:1668
0

hmm... nie powinno tak byc, chyba ze zmieniasz cos dynamicznie.
jedyne co mi przychodzi do glowy to wziac pod uwage, ze width oznacza szerokosc okna razem z ramka.
wiec napisanie np:

Kopiuj
button1.left:=width-button1.width;

bedzie sprawiac problemy.
jepiej uzywac ClientRect.Right - bo to zwroci Ci szerokosc wnetrza formy, przeznaczonego na umieszczanie komponentow.
mozliwe ze problem sprawia to przypisanie minimalnej szerokosci formy. pewnie tez ustawiana jest szerokosc formy razem z obramowaniem (ktore w przypadku visty jest szersze)...

KA
  • Rejestracja:prawie 15 lat
  • Ostatnio:około 12 lat
0

No właśnie nic nie zmieniam dynamicznie. Sam się dziwię. ClientRect.Right nie zdaje egzaminu. Usunięcie minimalnego rozmiaru okna też nie rozwiązuje problemu. Macie jeszcze jakieś propozycje? Będę się starał coś jeszcze wykombinować.

P.S. Da się włączyć opcje disabled dla jednego elementu w combobox'ie? Chodzi mi o coś takiego: Combobox1.Items.Strings[1].Enabled := False;?

olesio
  • Rejestracja:około 17 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Szczecin
  • Postów:4191
0

Chyba się w ComobBoxie standardowym nie da. Trzeba by było zrobić tak, że jak wybierzesz Item o Indeksie,
ktorego nie można wybrać to wtedy pokazuje się komunikat i ItemIndex ustawia się na -1 lub poprzedni Index.
Można to zrobić tak jak poniżej, ale tak się zastanawiam, jak zakładasz że jakiś Item nie jest do wybrania to w
takim razie po co go w ogóle pokazywać na ComboBoxie. Chyba, że chcesz zrobić Listę kategorii, ale to wtedy
bym używał do takich cełow TTreeView i operował na drzewku. Ewentualnie ListView i zdarzenia OnSelectItem.

Kopiuj
procedure TForm1.ComboBox1Select(Sender: TObject);
begin
  if ComboBox1.ItemIndex = 1 then
  begin
    ShowMessage('Nie możesz wybrać tego elementu.');
    ComboBox1.ItemIndex := -1;
  end;
end;

Pozdrawiam.
cimak
  • Rejestracja:ponad 22 lata
  • Ostatnio:ponad 9 lat
  • Postów:1668
0

mozna wykorzystac OwnerDraw i samemu narysowac "wygaszone" itemy:

ustaw OwnerDraw comboboxa na csOwnerDrawVariable lub csOwnerDrawFixed (nie pamietam czym to sie rozni...)

Kopiuj
procedure TForm1.ComboBox1DrawItem(Control: TWinControl; Index: Integer;
  Rect: TRect; State: TOwnerDrawState);
begin
 with ComboBox1 do
      begin
       canvas.Font:=ComboBox1.Font;

       if index=3 then //wygaszamy 4 item
           begin
            Canvas.Brush.Color:=Color;
            canvas.font.Color:=clGray;
           end
       else
           if (odSelected in State) then
              begin
               Canvas.Brush.Color:=clHighlight;
               canvas.Font.Color:=clHighlightText;
              end
           else
              begin
               Canvas.Brush.Color:=Color;
               canvas.font.Color:=font.Color;
              end;

       canvas.FillRect(rect);
       Canvas.TextOut(rect.Left+2,rect.Top, Items[index]);
       if (index=3) and (odSelected in State)
          then canvas.DrawFocusRect(rect);
      end;
end;

procedure TForm1.ComboBox1DropDown(Sender: TObject);
begin
  //w momencie wyswietlenia listy zapamietujesz ktory item byl zaznaczony...
  ComboBox1.Tag:=ComboBox1.ItemIndex;
end;

procedure TForm1.ComboBox1Click(Sender: TObject);
begin
  //jezeli wybrano "wygaszony" element, wybieramy ten ktory byl ostatnio. czyli nic nie zostaje wybrane.
  if ComboBox1.ItemIndex=3
     then ComboBox1.ItemIndex:=ComboBox1.Tag;
end;
papudrun
  • Rejestracja:ponad 22 lata
  • Ostatnio:ponad rok
0
kalwiremi napisał(a)

Macie jeszcze jakieś propozycje?

spróbuj jeszcze tak

Kopiuj
Button1.Anchors:=[akTop,akRight];

Programowanie to intymny stosunek intelektualny z komputerem :>
KA
  • Rejestracja:prawie 15 lat
  • Ostatnio:około 12 lat
0

Dokładnie tak mam zrobione.

Słuchajcie mam jeszcze jedno małe pytanko.

Tu macie kod pliku *.dpr projektu:

Kopiuj
program Edytor;

uses
  Windows, Forms, SysUtils,
  Unit1 in 'Unit1.pas' {Main},
  Unit2 in 'Unit2.pas' {O_programie},
  Unit4 in 'Unit4.pas' {Licencja},
  Unit3 in 'Unit3.pas' {Otwieranie},
  Unit5 in 'Unit5.pas' {Importowanie},
  Unit6 in 'Unit6.pas' {Edytuj_szukaj},
  Unit7 in 'Unit7.pas' {Tablica_znakow},
  Unit8 in 'Unit8.pas' {Pomoc},
  Unit9 in 'Unit9.pas' {Przebuduj_plik};

{$R *.res}
var
  localization: string;

begin
  Application.Initialize;
  localization := ExtractFilePath(Application.ExeName);
  if ((FileExists(localization + 'bin\core_4gta0975.gxc')) and (FileExists(localization + 'bin\core_4t10975.gxc')) and (FileExists(localization + 'bin\core_4t20975.gxc'))) then
    begin
      Application.Title := 'Edytor';
      Application.CreateForm(TMain, Main);
      Application.CreateForm(TO_programie, O_programie);
      Application.CreateForm(TLicencja, Licencja);
      Application.CreateForm(TOtwieranie, Otwieranie);
      Application.CreateForm(TImportowanie, Importowanie);
      Application.CreateForm(TEdytuj_szukaj, Edytuj_szukaj);
      Application.CreateForm(TTablica_znakow, Tablica_znakow);
      Application.CreateForm(TPomoc, Pomoc);
      Application.CreateForm(TPrzebuduj_plik, Przebuduj_plik);
      Application.Run;
    end
  else
    begin
      Application.MessageBox('Nie odnaleziono jednego ze składników aplikacji.  ', 'Edytor', MB_ICONERROR);
    end;
end.

Chciałem zrobić otwieranie plików przez 'Otwórz za pomocą...'. Cały rejestr mam zrobiony, ale chodzi mi o samą aplikację. Najprościej jest zrobić w zdarzeniu Main.FormCreate(); i jeśli parametry są różne od 0 i plik istnieje to wtedy otwiera plik, ale chodzi o to, że otwieranie musi wywoływać formę TOtwieranie, a nie jest ona jeszcze zainicjowana w momencie Main.FormCreate(); Nie mam pomysłu co z tym zrobić, a nie wiem czy możliwe jest wprowadzenie procedury takiego otwierania w pliku Edytor.dpr po linijce Application.Run;. Możecie mi coś doradzić?

KA
  • Rejestracja:prawie 20 lat
  • Ostatnio:minuta
  • Lokalizacja:Gorlice
0

A co za problem zmienić kolejność tworzenia formularzy? Zmień kolejność tworzenia:

Kopiuj
...
Application.CreateForm(TOtwieranie, Otwieranie);
Application.CreateForm(TMain, Main);
...

//EDIT: A Jednak sie nie da bo zmienia się główny formularz ale pokombinuję jeszcze

No i znalazłem proste obejście tego że zmienia się Application.MainForm
Do pliku .dpr dodajesz procedurę

Kopiuj
procedure SetAsMainForm(aForm:TForm);
var
  P:Pointer;
begin
  P := @Application.Mainform;
  Pointer(P^) := aForm;
end;

I podobnie jak poprzednio:

Kopiuj
...
Application.CreateForm(TOtwieranie, Otwieranie);
Application.CreateForm(TMain, Main);
SetAsMainForm(Main);
...
Application.Run;

Nie odpowiadam na PW w sprawie pomocy programistycznej.
Pytania zadawaj na forum, bo:
od tego ono jest ;) | celowo nie zawracasz gitary | przeczyta to więcej osób a więc większe szanse że ktoś pomoże.
olesio
  • Rejestracja:około 17 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Szczecin
  • Postów:4191
0

kalwiremi: jak chcesz zrobić otwieranie plików i to także przy otwartym już
programie to przenalizuj sobie kod projektu oraz modułu głownego, ktore
wrzuciłem pod poniższy adres. Może się to do czegoś także Tobie przyda.
http://www.speedyshare.com/files/22751293/multi_file_open.rar


Pozdrawiam.
Azarien
  • Rejestracja:ponad 21 lat
  • Ostatnio:około 14 godzin
0
kalwiremi napisał(a)
Kopiuj
  Unit1 in 'Unit1.pas' {Main},
  Unit2 in 'Unit2.pas' {O_programie},
  Unit4 in 'Unit4.pas' {Licencja},
  Unit3 in 'Unit3.pas' {Otwieranie},

i ty się w tym „połapujesz”? ponazywaj unity sensownie, ja mam system taki że w module uMain.pas jest forma fMain itd.

KA
  • Rejestracja:prawie 15 lat
  • Ostatnio:około 12 lat
0

Poradziłem sobie. Dzięki. Mam tylko jedno pytanie. Jak zrobię tak jak napisałeś z ustawianiem głównej formy, to gdy otwieram z parametru, to przy wyskoczeniu okienka 'Otwieranie' wyskakuje etykieta na pasku zadań, potem jak na tej formie otwieranie wybiorę otwórz, to ta etykieta na pasku zadań znika i po uruchomieniu formy 'Main' pojawia się jeszcze raz. Trochę denerwujące, masz jakiś sposób na ominięcie tego?

cimak
  • Rejestracja:ponad 22 lata
  • Ostatnio:ponad 9 lat
  • Postów:1668
0

a nie prosciej zamiast sie tak babrac zamiast do onCreate dac np w onShow?

KA
  • Rejestracja:prawie 15 lat
  • Ostatnio:około 12 lat
0

No więc tak. Podzieliłem wasze pomysły. Skorzystałem z procedury SetAsMainForm, a procedurę otwierania pliku wrzuciłem w Main.OnShow. Teraz śmiga ładnie. Mam do was chyba ostatnie pytanie odnośnie mojego programu. Gdy załaduje plik programem i fragmenty wyświetlają się w ValueListEditor, to po wykonaniu pewnej operacji następuje zmiana koloru tekstu w komórce za pomocą metody TCanvas. Tutaj macie fragment kodu:

Kopiuj
Main.ValueListEditor1.Canvas.Font.Color := clBlue;
Main.ValueListEditor1.Canvas.Brush.Style := bsClear;
Main.ValueListEditor1.Canvas.FillRect(Rect);
pom := Main.ValueListEditor1.Cells[ACol, ARow];
Main.ValueListEditor1.Canvas.TextOut(Rect.Left + 2, Rect.Top + 2, pom);

Chodzi o to, że jeśli wcześniej napis w komórce ValueListEditor'a bezpośrednio stykał się z suwakiem z prawej strony, to teraz zachodzi na niego o 1 piksel (napis jest o 1 piksel dłuższy). Macie propozycje pomocy? Bo ja osobiście nie jestem zbyt dobrze zorientowany w rysowaniu za pomocą TCanvas. Macie tutaj obrazek o co chodzi:

user image

zajcev
  • Rejestracja:ponad 17 lat
  • Ostatnio:ponad 7 lat
0
cimak
  • Rejestracja:ponad 22 lata
  • Ostatnio:ponad 9 lat
  • Postów:1668
0

mozesz zrobic tak:
zmierz jakiej szerokosci jest text: Canvas.TextWidth()
jesli jest szerszy niz szerokosc "Rect" to utnij go w odpowiednim miejscu i wypelnij np. kropkami.

Kopiuj
  with ValueListEditor1.Canvas do
       begin
         s := Main.ValueListEditor1.Cells[ACol, ARow];
         if TextWidth(s)>=rect.right then
            begin
              while (TextWidth(s+'...')>=rect.right) and (s<>'') do
                 Delete(s, Length(s), 1);
              s:=s+'...';
            end;

         Font.Color := clBlue;
         Brush.Style := bsClear;
         FillRect(Rect);
         TextOut(rect.left+2, rect.top+2, s);
       end;
KA
  • Rejestracja:prawie 15 lat
  • Ostatnio:około 12 lat
0

No niestety nie za bardzo to działa. Właściwie to jakby w ogóle to nie działało.

cimak
  • Rejestracja:ponad 22 lata
  • Ostatnio:ponad 9 lat
  • Postów:1668
0

u mnie dziala.
chociaz czekaj.. mozliwe ze przez to "with..do.." nie bierze tego "rect" ktore powinno.

KA
  • Rejestracja:prawie 15 lat
  • Ostatnio:około 12 lat
0

Niestety nie działa u mnie w żaden sposób. Ani z with... do, ani bez.

EDIT: Po prostu nie wyświetla tych kropek na końcu, nie skraca go, tylko wyświetla tak jak zawsze (wcześniej).

cimak
  • Rejestracja:ponad 22 lata
  • Ostatnio:ponad 9 lat
  • Postów:1668
0

to napisz co konkretnie nie dziala albo sam debuguj.

KA
  • Rejestracja:prawie 15 lat
  • Ostatnio:około 12 lat
0

Dobra poprawiłem, żeby działało i wygląda to tak (zmieniłem 'TextWidth(s) >= rect.right' na 'TextWidth(s) >= (rect.right - rect.left)'):

Kopiuj
with ValueListEditor1.Canvas do
begin
  s := Main.ValueListEditor1.Cells[ACol, ARow];
  if TextWidth(s) >= (rect.right - rect.left) then
    begin
      while (TextWidth(s + '...')>=(rect.right - rect.left)) and (s<>'') do
        Delete(s, Length(s), 1);
      s:=s+'...';
    end;
  Font.Color := clBlue;
  //Brush.Style := bsClear;
  FillRect(Rect);
  TextOut(rect.left + 2, rect.top + 2, s);
end;

Tylko musiałem wyłączyć Brush.Style := bsClear;, gdyż pod kropkami było widać poprzednie czarne litery, no nie fajnie to wygląda, ale teraz Brush rysuje białe tło i ono i tak zachodzi na suwak więc i tak trochę lipa... A nie da się po prostu zmniejszyć szerokość Rect'a?

KA
  • Rejestracja:prawie 15 lat
  • Ostatnio:około 12 lat
0

Jak na razie dałem sobie z tym spokój. Teraz mam takie pytanie, co byście poradzili w takiej sytuacji: W jakimkolwiek komponencie do edycji tekstu, chodzi mi głównie o Memo, RichEdit i Edit, gdy zaznaczę tekst, chciałbym zrobić, żeby po kliknięciu w zaznaczony tekst prawym przyciskiem myszy wyświetlało się przygotowane przeze mnie menu kontekstowe, a po kliknięciu lewym po prostu ustawiał się kursor normalnie w miejscu gdzie kliknąłem. Problemem jest jak dla mnie jak sprawdzić czy kliknięto w zaznaczony tekst, czy też nie. Z resztę raczej sobie poradzę. Mam jeszcze takie pytanko, czy mając zapisaną w zmiennej pozycje w tekście można sprawdzić czy dodano lub usunięto przed tą pozycją jakiś znak lub jeśli wklejono cały ciąg znaków lub usunięto to ile ich było?

papudrun
  • Rejestracja:ponad 22 lata
  • Ostatnio:ponad rok
0

chciałbym zrobić, żeby po kliknięciu w zaznaczony tekst prawym przyciskiem myszy wyświetlało się przygotowane przeze mnie menu kontekstowe, a po kliknięciu lewym po prostu ustawiał się kursor normalnie w miejscu gdzie kliknąłem.

podpinasz do memo popupMenu a potem w kodzie dla zdarzenia OnClick dla wybranej przez Ciebie pozycji w menu dajesz taki kod:

Kopiuj
ShowMessage(
copy(memo1.text,Memo1.SelStart,Memo1.SelLength)
);

w tym przypadku bedziesz miał message z zaznaczonym tekstem.

czy mając zapisaną w zmiennej pozycje w tekście można sprawdzić czy dodano lub usunięto przed tą pozycją jakiś znak lub jeśli wklejono cały ciąg znaków lub usunięto to ile ich było?

Wszystko można :) Mogłeś też założyć nowy temat zamiast ten odświeżać.

Kopiuj

Programowanie to intymny stosunek intelektualny z komputerem :>

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.