Q&A

  • [다시질문] MDI Menu 화면에 Label이나 Image를 사용시 값이 바뀌지가 않아요


빠른 확인 감사 드립니다.

그래서 저도 처음부터 다시 해보았습니다.
스샷은 첨부 했고요

3장의 스샷중 처음껏은 Design 화면이고
두번
10  COMMENTS
  • Profile
    석주현 2008.07.11 18:42
    <!--CodeS-->
    procedure TMainForm.tmr1Timer(Sender: TObject);
    begin
    Label1.Caption := TimeToStr(Now);
    MainForm.Perform(WM_SIZE, 0, 0);
    end;
    <!--CodeE-->

    편법입니다만 음 이 방법이 있긴 하겠네요. 결국 클라이언트 영역을 다시 뿌리게 하는 게 핵심인데
    이상하게 먹는게 별로 없네요. ㅡ_ㅡ;;
  • Profile
    김용호 2008.07.11 18:48
    답변 감사합니다.
    그런데 그것도 역시 안되네요.. ㅎㅎ

    혹시 다른 방법은 .....

    감사합니다..

    참 이상하지요...
  • Profile
    석주현 2008.07.11 18:49
    7.0 에서는 잘되는 데 이상하군요 ㅠ_ㅠ
  • Profile
    김용호 2008.07.11 18:54
    감사합니다..
    아무래도 6.0에선 안되는 듯하니
    버젼을 올려서 해봐야 겠어요..
    답변 정말로 감사합니다.
    행복하세요
  • Profile
    김용호 2008.07.11 19:16
    2007로 해보니 그냥은 안되고 알려주신 코드를 추가하니 되긴하네요.
    다시 그려서 그런가 화면이 약간 깜빡 거리는 듯 하지만요.

    감사합니다
  • Profile
    이정욱 2008.07.11 21:27
    Label1.Caption := TimeToStr(Now);
    Label1.Update;

    를 해보세요.

    참.. 그리고, 폼 OnCreate 에서 DoubleBuffered := True; 를 주시면 깜빡임은 없앨 수 있습니다.
  • Profile
    장성호 2008.07.11 21:29
    Label은 Graphic 컨트롤입니다.


    무슨 말이냐면 자신을 나타낼 핸들이 없기때문에 Parent의 DC에 자신을 그려줍니다.
    보통의 경우 Parent DC에 자신을 draw해주면 문제가 없는데

    MDI폼인경우 자신이 있는 위치가 Parent.Handle 인 Form.Handle이 아니라

    Form.ClientHandle 인것에서 문제가 발새합니다.

    vcl 소스를 보면 Label.Caption을 수정할때 맨마지막에 InvalidateControl 함수가 호출됩니다.

    <!--CodeS-->
    procedure TControl.InvalidateControl(IsVisible, IsOpaque: Boolean); 함수에서

    ...

    begin
    if (IsVisible or (csDesigning in ComponentState) and
    not (csNoDesignVisible in ControlStyle)) and (Parent <> nil) and
    Parent.HandleAllocated then
    begin
    Rect := BoundsRect;
    InvalidateRect(Parent.Handle, @Rect, not (IsOpaque or
    (csOpaque in Parent.ControlStyle) or BackgroundClipped)); //Parent에서 자신이 있는 영역을 무효화 하는 메세지를 보냅니다.
    end;
    end;
    <!--CodeE-->

    저기 InvalidateRect 함수에 문제가 있는것이죠

    InvalidateRect에서 Parent.Handle 이 아니라 Form.ClientHandle 로 해야하구 Rect도 mdi에 맞춰서 조정해줘야 하구요

    결론적으로 다음과 같이하면 문제가 해결될것입니다.

    <!--CodeS-->
    procedure TForm1.Timer1Timer(Sender: TObject);
    var
    rc: TRect;
    begin
    Label1.Caption:=FormatDateTime('yyyy-mm-dd hh:nn:ss',Now); //Label1.Caption을 수정하고

    rc:=Self.ClientRect;
    InvalidateRect(self.ClientHandle, @rc, true); //InvalidateRect 를 Form의 ClientHandle을 넣어서 호출해줍니다.
    end;
    <!--CodeE-->

    그런데 위함수에도 문제가 하나 있는데...
    InvalidateRect 호출할때 Rect가 홈 Client전체 라는것입니다.
    MDI의 경우 Label의 Rect(Lebel.left , Lebel.top ...) 으로 하니까 안되더군요

    Label의 Left , Label.top은 Form의 ClientRect를 기준으로 하지만
    MDI의 Client의 Rect가 Form의 ClientRect 와 같지가 않더군요

    아래는 MDI폼의 왼쪽에 Panel이 Align=alLeft 로 놓여있는경우에 처리입니다.

    <!--CodeS-->
    procedure TForm1.Timer1Timer(Sender: TObject);
    var
    rc: TRect;
    begin

    Label1.Caption:=FormatDateTime('yyyy-mm-dd hh:nn:ss',Now);

    rc:=Rect(0,Label1.Top, Self.Width,Label1.Top+ Label1.Height); //이 영역을 구하는 문제가 아직 남아있음...

    InvalidateRect(self.ClientHandle, @rc, true);

    end;

    <!--CodeE-->






  • Profile
    석주현 2008.07.11 21:51
    <!--CodeS-->
    procedure TMainForm.tmr1Timer(Sender: TObject);
    begin
    Label1.Caption := TimeToStr(Now);
    InvalidateRect(self.ClientHandle,nil,False);
    end;
    <!--CodeE-->

    아 그러고 보니 이렇게 하면 일단 되겠네요. ㅎㅎ 장성호님 저도 이번에 하나 배웠네요.
    감사합니다.
  • Profile
    장성호 2008.07.11 22:19
    찾았습니다.

    InvalidateRect(self.ClientHandle,nil,False); 이렇게 하면
    MDI Client 전체를 다시 repaint 하게 됩니다.


    그래서 Label 영역만 InvalidateRect 해주려면?
    Label의 ClientRect를 InvalidateRect 함수로 전달해 줘야하는데...

    문제는 Label의 Left , Top 의 기준이

    Form의 Handle의 Client 영역 기준이지
    MDI Handle인 Form.ClientHandle 기준이 아니라는것입니다.

    Label의 CleintRect 값을 MDI 기준으로 바꿔서 InvalidateRect 호출해주는 함수입니다.

    <!--CodeS-->

    procedure TForm1.Timer1Timer(Sender: TObject);
    var
    rc,rc_mdi: TRect;
    pt_delta,pt_mdi_ctrl: TPoint;
    begin
    Label1.Caption:=FormatDateTime('yyyy-mm-dd hh:nn:ss',Now);

    GetWindowRect(self.ClientHandle,rc_mdi);
    pt_delta.X:=(self.Width - ClientRect.Right ) div 2 ;
    pt_delta.Y:= self.Height - ClientRect.Bottom - pt_delta.X;
    pt_mdi_ctrl:=Point((Label1.Left + pt_delta.X + self.Left ) - rc_mdi.Left ,(Label1.Top + pt_delta.Y + self.Top ) - rc_mdi.Top );
    rc:=Rect(pt_mdi_ctrl.x,pt_mdi_ctrl.y,pt_mdi_ctrl.x+Label1.Width,pt_mdi_ctrl.y+Label1.Height);
    InvalidateRect(self.ClientHandle, @rc, true);
    end;

    <!--CodeE-->

    저도 MDI Form에서 Graphic 컨트롤에 이런 문제가 있는지 오늘 처음 알았습니다.

    그럼 ..
  • Profile
    김용호 2008.07.12 10:36
    정말 감사들 합니다.
    저의 한 질문에 이렇게 신경을 써 주셔서 감사합니다
    모두 행복하세요..
    • steps
      2008.07.18 04:52
      procedure TForm1.btn1Click(Sender: TObject); var yr, mn, dy, i, days : word; function getDaysO...
    • 따따부따
      2008.07.18 20:24
      정말 감사합니다. ㅜㅜ
    • 따따부따
      2008.07.21 20:04
      위 내용대로 프로그램을 만들고 델파이7 에서 기본적으로 지원하는 WeekOfTheYear(Now) 를 써서 프로그...
    • steps
      2008.07.21 22:20
      델파이에서 주는 값은 요일을 고려한 역서의 주차입니다. 제가 올린 코드에서 DecodeDate를 DecodeDateF...
    • Crazy™
      2008.07.25 00:22
      주차를 구하는 방식이 몇가지 있는데요. 델파이 컴퍼넌트중 datetTimePicker ?든가. 달력보는 컴퍼넌트...
    • 방석배
    • 2008.07.18 02:46
    • 0 COMMENTS
    • /
    • 0 LIKES
    • steps
      2008.07.18 02:57
      function MyDLL(p_Port: Integer; p_InStr:PChar; var p_OutStr:PChar):integer; cdecl; 로 해보시죠.
    • 강신구
      2008.07.18 03:05
      이미 stdcall -> cdecl 로 바꿔봤는데 안되던군요..
    • 최용일
      2008.07.18 08:00
      참조에 의한 호출이니까 아래와 같이 주소를 넘겨줘야 될 것 같은데요... int rc = MyDLL(input_port, ...
    • 최용일
      2008.07.18 08:04
      TCP통신을 하셔야 할것 같네요... 양쪽에 모두 TCP통신을 하는 프로그램이 있어야 하고, 한쪽은 서버역...
    • 김성욱
      2008.07.19 04:12
      자료실에 보시면 한델 2차 세미나 자료있습니다. 소스 보시면 금방 해결 할 수 있습니다. 참고하...
    • 미소나눔
      2008.08.01 23:55
      저희도 회사에서 공지사항을 전파하기위해 비슷한걸 만든적이 있는데.. 뭐 대충 참고하세용.. // ...
    • 전문성
    • 2008.07.16 19:54
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 이정욱
      2008.07.17 10:25
      프로그램내에 자신의 어플리케이션 이름을 가지고 무엇인가 하는 부분이 있다면..확인해보세요.. 그런...
    • 임형호
      2008.07.16 02:52
      post 해보세요.
    • 석주현
      2008.07.16 06:46
      혹시 USB 드라이브나 외장하드 붙여서 작업하시다가 빼신게 아닌지 궁금하네요. 그럴경우 프로젝트가 ...
    • 가르쳐주삼
      2008.07.16 19:43
      계속 델파이 설치 CD 를 넣고 사용해야 되나요......?
    • 석주현
      2008.07.17 03:30
      아 그게 아니고요. 혹시 프로젝트 파일 중에 E 드라이브에서 읽어온 파일이 있나 없나 확인을 해보세...
    • 가르쳐주삼
      2008.07.18 20:50
      아~ 네~ 확인해보겠습니다.
    • 강정구
    • 2008.07.15 20:50
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 임형호
      2008.07.16 02:59
      일단 footer를 먼저 만드셔야돼요. RealGrid.Footers.Add; 이렇게하면 footer가 만들어지죠. 그후...
    • 장종운
    • 2008.07.15 19:23
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 이윤도
      2008.07.16 18:30
      네~ 가능한걸로 알고있구요. http://fadelphikorea.com/index.html <-- 델파이 FA개발자들을 위한...
    • 석주현
      2008.07.12 16:10
      http://www.codegear.com/downloads/regusers/delphi 등록 유저면 여기서 다운 가능 합니다. Quick...
    • 황경수
    • 2008.07.12 01:09
    • 5 COMMENTS
    • /
    • 0 LIKES
    • 장성호
      2008.07.12 01:21
      SysUtils.ShortDateFormat 을 바꾸지 말고 DateTimePicker의 Format을 바꿰세요 procedure TF...
    • 황경수
      2008.07.14 20:00
      장성호님 답변 감사 합니다. 그런데, 제가 질문을 잘못 한거 같네요. 지금 제가 만든 프로그램은 ...
    • 최용일
      2008.07.14 21:16
      간단하게 하세요... 디비에 넣을때 아마도 문자열로 넣으시는것 같은데... FormatDateTime을 써서 포맷...
    • 장성호
      2008.07.14 21:29
      프로그램내에서 무조건 항국어방식 '(YYYY-MM-DD)' 으로 처리하는게 목적이시라면? 님께서 질문하시기...
    • 황경수
      2008.07.17 19:07
      아... 제가 뭔가 실수 했었네요. 잘 돌아 가네요. 장성호님, 최용일님 정말 감사 드립니다. 그럼 좋은...
    • 김상진
    • 2008.07.11 21:52
    • 6 COMMENTS
    • /
    • 0 LIKES
    • 이정욱
      2008.07.11 22:53
      private 에 Mainfrm : TfrmMain; 이라고 메인 폼 변수를 선언하시고, procedure ShowTestDlg(App:TA...
    • 김상진
      2008.07.11 22:56
      마찬가지 결과가 나옵니당 ^^
    • 이정욱
      2008.07.11 23:05
      아.. 그렇군요. 이런형식은 한번도 해보질 못해봤었네요.. 혹시 소스 있으시면 올려주세요 ^^;
    • 김상진
      2008.07.11 23:10
      위에 소스 있는데요 ㅠㅠ
    • 장성호
      2008.07.12 00:42
      음... LoadLibrary로 같은 dll을 두번하나 열번 load하나 결과는 같은놈입니다. LoadLibrary후...
    • 김상진
      2008.07.12 01:44
      속이 시원하니 잘 됩니다.. 감사합니다...
    • 이우석
    • 2008.07.11 20:50
    • 2 COMMENTS
    • /
    • 0 LIKES
    • 이정욱
      2008.07.11 21:30
      델파이 개발 환경 내에서 나는 익셉션이라면 정상입니다. 인디에서는 파일이 존재 한다면 위의 익셉션...
    • 사다리
      2008.11.19 08:43
      FTP.Get(s, SaveFile.FileName, True, FTP.ResumeSupported); 요 구문에서요 세번째 파라미터 값이...
    • 김용호
    • 2008.07.11 17:41
    • 10 COMMENTS
    • /
    • 0 LIKES
    • 석주현
      2008.07.11 18:42
      <!--CodeS--> procedure TMainForm.tmr1Timer(Sender: TObject); begin Label1.Caption := Ti...
    • 김용호
      2008.07.11 18:48
      답변 감사합니다. 그런데 그것도 역시 안되네요.. ㅎㅎ 혹시 다른 방법은 ..... 감사합니다.. ...
    • 석주현
      2008.07.11 18:49
      7.0 에서는 잘되는 데 이상하군요 ㅠ_ㅠ
    • 김용호
      2008.07.11 18:54
      감사합니다.. 아무래도 6.0에선 안되는 듯하니 버젼을 올려서 해봐야 겠어요.. 답변 정말로 감사합니...
    • 김용호
      2008.07.11 19:16
      2007로 해보니 그냥은 안되고 알려주신 코드를 추가하니 되긴하네요. 다시 그려서 그런가 화면이 약간 ...
    • 이정욱
      2008.07.11 21:27
      Label1.Caption := TimeToStr(Now); Label1.Update; 를 해보세요. 참.. 그리고, 폼 OnCreate 에...
    • 장성호
      2008.07.11 21:29
      Label은 Graphic 컨트롤입니다. 무슨 말이냐면 자신을 나타낼 핸들이 없기때문에 Parent의 DC에 자...
    • • • •