2012-04-18 2 views
3

* SetWindowLong (myForm.hWnd, GWL_HWNDPARENT, parentHwnd) *가 왜 멈추나요?SetWindowLong Hanging

이 세 가지 단계를 일관되게 수행하여이 문제를 재현 할 수 있습니다.

  1. 는 .NET 양식을 작성
  2. Initalize WaitWindow COM 개체는 .NET 양식은 VB6에서
  3. 가 SetWindowLong에 방법을

C 번호를 호출 처리 통과하면서 COM 개체에이 ShowWindow를 호출 Windows 응용 프로그램 (응답하지 않음)

private static void Main(string[] args) 
{ 
     Form form = new Form(); 
     form.Show(); 

     Interop.WaitWindow waitWindow = new Interop.WaitWindow(); 
     waitWindow.ShowWindow(form.Handle.ToInt32(), Language.RISEnglish); 
} 

C# 콘솔 응용 프로그램 (하지 않습니다 끊기)

private static void Main(string[] args) 
{ 
     IntPtr handle = Process.GetCurrentProcess().MainWindowHandle;  

     Interop.WaitWindow waitWindow = new Interop.WaitWindow(); 
     waitWindow.ShowWindow(handle.ToInt32(), Language.RISEnglish); 
} 

VB6 코드 조각

Public Sub ShowWindow(ByVal parentHwnd As Long, ByVal language As Language) 

    SetWindowLong(myForm.hWnd, GWL_HWNDPARENT, parentHwnd) 'Hangs Here 
    CenterWindow (parentHwnd) 

    myForm.ShowRetrieving (language) 
    myForm.Show (vbModal) 
End Sub 

정말 당신의 도움 :)

편집

I 감사하겠습니다 SetWIndowLong이 b가 아니어야 함을 이해해야합니다. e 부모를 변경하려면 호출하지만 .NET 폼 핸들을 사용할 때만 왜 멈추는 지 이해하려고합니다.

EDIT2

는 지금 문제가 SetWindowLong에 있지만, 실제 핸들 자체에 관련이 없습니다 생각합니다. 아직 조사 중이지만 .NET에서 VB6 코드를 호출하면 RPC 스레드가 만들어집니다. 아직 확실하지 않지만 크로스 스레딩 문제와 관련이 있다는 느낌이 들었습니다.

+1

참고 : 코드의 VB6 부분을 기존 시스템의 일부로 업데이트 할 수 없으며이 특정 조건까지 "미세 조정"되었습니다. – silentfrost

답변

3

정확히 무슨 일이 있었는지와 문제를 해결하는 방법을 알아 냈습니다. [STAThread] 속성을 사용하여 기본 진입 점을 지정하지 않았으므로 대신 MTA를 기본값으로 설정했습니다. 이것은 VB6 코드를 호출 할 때 RPC 콜백 스레드를 만들었고 UI가 실행되는 주 스레드에 대한 호출을 마샬링하지 않았 음을 의미합니다.

피터 모텐슨은 이것에 대해 good explanation를 썼다 :

STA 모델이 스레드로부터 안전하지 COM 개체에 사용됩니다. 그 그들은 자신의 동기화를 처리하지 않는다는 것을 의미합니다. 의 일반적인 사용은 UI 구성 요소입니다. 따라서 다른 스레드가 개체와 상호 작용해야하는 경우 (예 : 양식의 단추 누르기) 메시지가 으로 STA 스레드에 정렬됩니다. 창 양식 메시지 펌핑 시스템의 예입니다.

2

MSDN 설명서는 명확

당신은 자식 윈도우의 부모를 변경하려면 GWL_HWNDPARENT 지수 SetWindowLong 함수를 호출하지 않아야 말한다. 대신 SetParent 함수를 사용하십시오.

+0

설명서를 읽지는 않았지만 전화를하면 안됩니다. VB6 코드를 많은 모듈이 참조하는 기존 코드로 수정할 수 없다는 사실을 잊어 버렸습니다. 내가 .NET 형식 핸들을 전달하지 않는 한 왜 작동하는지 궁금합니다. – silentfrost

+0

일 수 있습니다. 이로 인해 메시지가 전송 될 수 있습니다. windbg를 사용하여 각 스레드에 대해 스택 덤프를 가져 오십시오. http://blogs.msdn.com/b/oldnewthing/archive/2007/12/28/6882760.aspx – John

+3

MS는 사용자가이 작업을 수행 할 수 없다고 설명 할 필요가 없습니다. 그들은 그렇게하지 말라고 말합니다. 그러지 마십시오. –

1

64 비트 시스템에서 실행 중이십니까? VB6 응용 프로그램이 32 비트 응용 프로그램입니까? 이 시나리오에 해당하는 경우 RPC 호출이 생성되는 이유를 설명하고 불법적 인 해킹이 작동하지 않는 이유를 설명합니다. 이 경우, 나쁜 소식은 현재 작동시킬 수있는 방법이 있다는 것입니다.

.NET 컨트롤 may change during the lifetime of the control의 부하 처리 Windows 핸들도 알고 있어야합니다. 이 문제에 대한 토론은 this question을 (를) 참조하십시오.

+0

나는 Windows XP SP3 32 비트에서 모든 것을 돌리고 있는데, 하나님 께 감사드립니다 ... 그의 프로젝트에는 이미 두통이 충분합니다. 생각해 줘서 고마워. – silentfrost