안녕하세요 델파이 개발자 메르세데스입니다.
지난 시간에 폼을 패널 안에 넣은 방법을 해봤는데요.. 좀 더 나아가 delphi의 dll 프로그램안에 있는 특정 폼을 메인 프로그램 내 panel에 넣을 수 있는 방법이 없지 않을 것 같아 고민해봤습니다.
보통은 dll프로그램은... ShowModal로 띄워서 사용했었거든요 이곳 저곳에 붙일 수 있으니 나름대로 편하다고 생각했었는데 문제는 이렇게 띄워진 창을 닫지 않으면 아무것도 할 수 없기 때문에 불편합니다.
나름대로의 시행착오가 있었지만 됩니다. 하지만 이것이 100점짜리 정답은 아닌 것 같습니다. 차차 해결하는 것으로 하고.. 좋은 의견이 있으시면 공유해주셨으면 좋겠습니다. ^^;
방법은 생각보다 간단합니다. 지난 시간에 패널 안에 폼을 넣는 방법을 조금 응용하면 되거든요..
1. dll쪽 구문입니다.
function type으로 만들고.. 반환값을 TForm type으로 하면 되겠습니다.
사실 저도 고정관념이 좀 있어서.. Function 이라고 하면.. true/false 혹은.. text같은 문자열만 사용했었는데 폼 자체를 반환 할 수 있습니다.
Function ShowDLLRTN: TForm;StdCall;
....
Function ShowDLLRTN: TForm;StdCall;
begin
AAAS1:= TAAAS1.Create(AAAS1);
Result := AAAS1;
end;
2.EXE파일쪽 구문입니다.
호출 방식이 Function type인거 말고는 정말 별거 없죠.. 눈치채셨겠지만.. TForm Type 으로 받아서.. 이걸 패널에 넣는 것 을 구현하면 끝입니다. 사실 도전 하는 것이 쉽지 않지, 일단 해보면 별것 아닌 것이 많죠..
정말 별것 아니지만.. 구현하는 것과 이로 인해 생기는 잡다한 문제들 해결하는데 2일 정도 시간이 걸린 것 같습니다 ㅜㅜ
TShowDLLRTN = function: TForm; StdCall;
.....
[Button구현부분]
procedure AAAA.RzBitBtn18Click(Sender: TObject);
var LibHandle: THandle;
ShowDLLRTN: TShowDLLRTN ;
aPN : TForm;
begin
aPN := TForm.Create(nil);
LibHandle := LoadLibrary('호출DLL이름');
try
if LibHandle = HINSTANCE_ERROR then
raise EDLLLoadError.Create('Unable to Load DLL');
@ShowDLLRTN:= GetProcAddress(LibHandle,'ShowDLLRTN');
if not (@ShowDLLRTN= nil ) then
begin
aPN:= ShowDLLRTN; //DLL의 결과를 aPN이라는 변수에 받는다
aPN.ParentWindow := RzPN10.Handle;
//aPN.Parent := RzPN10;
aPN.Align := alClient;
aPN.BorderStyle := bsNone;
aPN.WindowState := wsMaximized;
aPN.Visible := true;
RzPN10.Visible := true;
end
else
ShowMessage(IntToStr(GetLastError));
finally
end;
패널안에 DLL프로그램내 만들어 놨었던 폼이 들어오게 되니 참 신기하네요.. 무엇보다.. 재사용이 가능하기 때문에 훨씬 효율성이 높은 코딩이 가능해지겠죠.. 여기 저기 다 붙일 수 있으니까요!
하지만.. 큰 문제는.. 메모리 해제 방법인데요. AAA.Parent = [패널] 이런 코딩이 안 먹힌다는 것입니다.
물론 오류는 안나지만.. 화면내에 표시가 안되는 문제가 있어 한참 찾아보니.. AAA.ParentWindow = [패널].Handle
이런 방법으로 하니 표시가 됩니다 하지만 이렇게 처리 하다 보니 dll로 부터 결과를 넘겨 받은 AAA라는 TForm type의 변수를.. 사용을 다 하고 나서 제대로 해제 처리하지 않으면 지겹도록 아래의 Code:1400 에러를 보게 될 것입니다.
저는 어쩔 수 없이.. 전역변수를 이용하여
글로벌hWnd := aPN.Handle;
if 글로벌hWnd <> 0 then
begin
SendMessage(글로벌hWnd , WM_CLOSE, 0, 0); //특정핸들프로그램 종료
글로벌hWnd:= 0;
end;
FormCloseQuery와.. 버튼 시작 부분에 넣어 놓는 것으로 해결하긴 하였는데 소스가 길어지고 말았네요ㅜㅜ
하지만.. 재사용성을 높일 수 있다는 가능성과.. dll-ModalForm의 불편함을 해결할 수 있는 방법으로.. 좋은 결과를 얻은 것 같습니다.
근데 구현해 놓고 보니 2가지 불편함이 생겼습니다. 패널 안으로 들어온 dll폼을 exe프로그램에서 제어하는 방법과 그 반대에서 제어하는 경우죠 예전엔 ModalForm이기 때문에 이런 불편함에 대해 전혀 고민을 안 해도 됐었거든요 그 창이 닫히기 전까진 어차피 아무것도 안되니까요...
다음 시간에는 이런 고민을 해결하는 방법에 대해 연구해보고 포스팅 해보도록 하겠습니다. 감사합니다.
'프로그래밍 > delphi' 카테고리의 다른 글
델파이 dll 모달폼을 일반 폼으로 변경하기 위한 팁.. (0) | 2015.05.29 |
---|---|
delphi TMS 달력에 특정 날짜에 색 표시하기.... (0) | 2015.04.27 |
delphi exe와 프로그램안에 embadded된 dll프로그램간의 상호간 제어하기 (0) | 2015.04.11 |
delphi 폼을 패널안에 넣으려면 어떻게 하면 될까요? (0) | 2015.04.10 |
델파이(delphi) 시간을 24시간제로 표현하고싶어요.. (0) | 2015.03.24 |
댓글