컬럼헤더에 여러줄로 캡션을 쓸 수 있고, 컬럼헤더를 병합하고, 체크박스를 디자인 타임에서 구현하는
StringGrid와 비슷한 사용자 패키지 컴포넌트를 만들다가 (수정?)하다. 이상한 현상을 발견했다.
자료가 2000건 정도일때
세로스크롤바의 상버튼(SB_LINEUP), 하버튼(SB_LINEDOWN)으로 이동은 잘 된다.
그런데 세로 스크롤바의 썸(Thumb)을 드래그 하여 자료를 이동하면 1638건에서 더이상 드래그가
되지 않는다. (행의 높이가 20일때)
이유는 세로스크롤과 관계된 윈도우 메시지는 TWMVScroll 였다. Messages 유닛에 선언되어 있는데
선언부분을 보면 TWMVScroll = TWMScroll 처럼 TWMScroll Class 이다.
TWMScroll = record
Msg: Cardinal;
MsgFiller: TDWordFiller;
ScrollCode: Smallint; { SB_xxxx }
Pos: Smallint; <- 문제원인
ScrollCodePosFiller: TDWordFiller;
ScrollBar: HWND;
Result: LRESULT;
end;
문제의 원인은 바로 Pos 멤버가 Smallint 타입 (-32768~32767) 이다.
행의 높이가 20일때 32767/20 = 1638 이므로 그리드의 헤드컬럼 포함해서 약 1638건만 드래그 되었던 것이다.
물론 스크롤바의 상버튼 하버튼은 TWMVScroll 윈도우 메시지를 사용하지 않고 직접 약 20씩 상하로 이동되게 코딩되어 있어
잘 작동되었던 것이다.
며칠 고생하여 해결했다.
Windows 유닛의 TScrollInfo = tagSCROLLINFO 구조체인데.
tagSCROLLINFO = record
cbSize: UINT;
fMask: UINT;
nMin: Integer;
nMax: Integer;
nPage: UINT;
nPos: Integer;
nTrackPos: Integer;
end;
GetScrollInfo 함수를 통해
function GetScrollInfo(hWnd: HWND; BarFlag: Integer; var ScrollInfo: TScrollInfo): BOOL; stdcall;
스크롤바의 모든 정보를 알수 있다.
또한 썸드래그시 위치인 nTrackPos 멤버가 integer타입이다 -2147483648 ~ 2147483647 (약21억)
이 정도면 이론상 약 1억 건도 스크롤된다.
그래서 원래 윈도우메시지 TWMVScroll을 사용해던 부분을
FVertOffset := Msg.Pos; //Msg는 윈도우메시지 TWMVScroll, FVertOffset 는 변경할 위치
다음처럼 GetScrollInfo 함수를 통해 해결했다.
var si : TScrollInfo;
rt : Boolean;
rt := GetScrollInfo(Handle, SB_VERT, si); // 꼭 rt로 할당하고나서 비교해야한다.
if rt then
FVertOffset := si.nTrackPos;
함수의 리턴값인 rt 가 True면 nTrackPos가 현재의 썸위치를 가져온다.
가져온 썸위치를 세로 스크롤바의 위치에 대입하면 된다.
(참고)
https://msdn.microsoft.com/en-us/library/windows/desktop/bb787583(v=vs.85).aspx
또한 일반적인 TMemo 컨트롤의 세로 스크롤바를 맨아래로 강제 이동시키는 방법은
Memo1.Perform(WM_VSCROLL, SB_BOTTOM, 0); // Memo1 맨아래로 이동
'델파이' 카테고리의 다른 글
MS Office2013 ADO, OLEDB 제외 AccessDatabaseEngine 별도 설치 (0) | 2015.08.28 |
---|---|
델파이xe에서 TImage 의 gif 포맷 TGIFImage에서 TJvGIFImage 으로 변경됨 (0) | 2015.08.03 |
델파이 배열 상수 사용법, 로컬 디렉토리에서 특정경로의 상위폴더 얻기 (0) | 2015.06.05 |
델파이 TDBGrid 다중 선택시 깔끔한 선택 모양 (0) | 2015.05.16 |
ADO 이용한 엑셀(*.xlsx), 콤마구분자파일(*.csv), 탭구분자파일(*.txt) 자료 읽기 (0) | 2015.01.01 |