2011-11-26 6 views
2

콘솔의 텍스트 색을 지정된 색으로 설정하고 한 줄 이상을 인쇄 한 다음 색 구성표를 다시 원래 색으로 변경하려고합니다. 여기에 내가 무엇을 가지고 :두 번째 GetStdHandle 호출 "invalid"핸들을 반환합니다.

Function SetConsoleTextColor(NewColor As UInt16) As UInt16 
    Declare Function SetConsoleTextAttribute Lib "Kernel32" (hConsole As Integer, attribs As UInt16) As Boolean 
    Declare Function GetStdHandle Lib "Kernel32" (hIOStreamType As Integer) As Integer 
    Declare Function GetConsoleScreenBufferInfo Lib "Kernel32" (hConsole As Integer, ByRef buffinfo As CONSOLE_SCREEN_BUFFER_INFO) As Boolean 
    Declare Sub CloseHandle Lib "Kernel32" (HWND As Integer) 

    Const STD_OUTPUT_HANDLE = -12 

    Dim conHandle As Integer = GetStdHandle(STD_OUTPUT_HANDLE) 
    Dim buffInfo As CONSOLE_SCREEN_BUFFER_INFO //A structure defined elsewhere 
    If GetConsoleScreenBufferInfo(conHandle, buffInfo) Then 
     Call SetConsoleTextAttribute(conHandle, NewColor) 
     CloseHandle(conHandle) 
     Return buffInfo.Attribute 
    Else 
     Return 0 
    End If 
End Function 

이것은 첫 번째 호출에서 잘 작동합니다. 콘솔의 새 출력에 대한 텍스트 색이 변경되고 이전 특성이 반환됩니다. 그러나 이것을 다시 호출하여 속성을 재설정하면 GetStdHandle은 이전 호출과 동일한 핸들을 반환하지만 지금은 유효하지 않습니다 (닫은 이래로).

이렇게하면 오류가 발생합니다. 핸들을 사용합니다. 내가 정적 변수 conHandle을 만 0 인 GetStdHandleconHandle 경우 호출하는 경우 제대로 작동 (RealBasic의 새로운 숫자 변수의 디폴트 값입니다.)

나는 항상 나 자신 뒤처리를 들었다. 이 핸들을 열어 두어야합니까?

+3

네, 스스로 청소해야하지만 다른 사람의 재산도 존중해야한다고 들었어 야합니다. 이 경우 콘솔 핸들을 만들지 않았으므로 콘솔 핸들도 제거하면 안됩니다. –

+0

나는 손잡이를 만들었다 고 생각했었다. 적어도 그것이 내게 속한 것 같았다. –

+1

GetStdHandle은 핸들을 만들지 않고 기존 핸들을 가져옵니다. 핸들 생성 함수는 CreateFile, CreateMutex 등입니다. –

답변

3

예 핸들을 열어 두어야합니다.

이 핸들은 프로세스가 종료 될 때 자동으로 닫힙니다.

+0

나는 본다. 고마워. –

0

다양한 사이트에 대한 연구를 수행하면 GetStdHandle에서 반환 한 핸들에서 CloseHandle을 사용하면 좋지 않은 일이 발생할 수 있습니다. 종종 사람들의 대답은 하나를 만드는 것보다는 핸들을 생성하기 때문에 (Get이 아니라 Create라는 이름이 함수 이름에 있음) 시스템에 의해 생성 된 핸들을 가져 오는 것이 분명해야하며, 이것을 닫는 것은 나쁜 생각입니다. 그러나 실제 답변은 분명한 것은 아닙니다 (슬프게도). GetStdHandle에서는 사실이지만 핸들과 관련된 모든 Get 함수가 실제로 기존 핸들을 가져 오는 것은 아닙니다. 일부는 새로운 핸들을 만듭니다. 예를 들어 GetDC는 실제로 장치 컨텍스트에 대한 새 핸들을 만들고 새 핸들이므로 CloseHandle로 제대로 닫아야합니다. 일부 사람들의 응답과 달리 함수에 Create라는 단어가 포함되어 있으면 새 핸들을 만들고 Get이라는 단어가 들어 있으면 시스템에서 이미 만든 핸들 만 참조한다는 규칙은 없습니다. 그런 규칙은 전혀 없습니다. 핸들을 실제로 닫아야 할 때를 어떻게 알 수 있습니까? 한 가지 방법은 MSDN에서 CloseHandle이 such-and-such 함수에서 반환 된 핸들에 사용해야한다고 명시하지 않는 경우 해당 핸들에서 CloseHandle을 사용하지 않아야한다고 가정하는 것이 안전하다는 것입니다. 그것을 파악하는 또 다른 방법은 시행 착오입니다. CloseHandle을 사용하면 프로그램에 더 많은 버그가있는 경우 CloseHandle을 사용하지 마십시오. CloseHandle을 사용하지 않으면 프로그램에 더 많은 버그가 발생하게되고 CloseHandle을 사용하십시오. 나는 종종 이러한 접근 방식의 조합을 사용합니다. MSDN 문서를 따른 후 내 프로그램에 버그가있는 것 같지만 MSDN에서 지정한 것과 다르게 처리하는 것은 프로그램의 버그를 줄이는 경향이 있습니다. 시행 착오를 통해 작동하는 것으로 결정했습니다.

+0

'GetDC'는 디바이스 컨텍스트를 "생성"하지 않으므로 결과에'CloseHandle'을 호출하면 안됩니다. 글쎄, 사실, 당신은'CloseHandle'을 * 어떤 GDI 객체 핸들에서도 호출하지 않습니다. 'CreateDC'에 해당하는 클린업 함수는'DeleteDC'입니다. 당신은'GetDC'에서 얻은'HDC'에 이것을 사용하지 않습니다. 'GetDC'의'HDC'는 나중에'ReleaseDC'로갑니다. (그리고 OWN DC 스타일을 가진 클래스 나 윈도우에 대한 특별한 규칙이 있습니다.) –

+0

제 말은,이 답변에 숨겨진 유효한 포인트가 있습니다. 즉, 문서를 읽음으로써 CloseHandle에 핸들을 넘길 것인지, API가 'C' -'r'-'e'-'a'-'t'-'e' 문자로 시작하는지 여부는 아닙니다. 하지만 불행히도 벽에 묻혀 있습니다. –

관련 문제