UNIQLOCK을 달고 나서 카테고리 트리의 서브 카테고리가 열리지 않으면서 스크립 오류가 나는 문제가 있었어요.

아마도 UNIQLOCK 스크립트를 달면서 뭔가 오류가 있었겠죠.
UNIQLOCK은 외부의 단일 스크립트이고 그 안에 두 개의 스크립트가 추가로 로드되는데요, 이 중 setLayer.js 라는 파일에 있는 코드가 문제를 일으키네요. 원본 코드는 다음과 같습니다.

function showLayer(layerID,value){
// alert(layerID);
 document.getElementById(layerID).style.visibility = value;
}

평범하죠? 문제는 style.visibility가 설정되어 있지 않은 layer에서는 이 코드가 오류를 발생시킨다는 점이에요. 게다가 showLayer라는 함수는 티스토리의 common2.js 파일에서도 사용하고 있는 이름인데 두 펑션의 정의가 다르니까 당연히 티스토리의 showLayer를 사용할 때 문제가 발생할 거에요. 티스토리의 showLayer 함수는 다음과 같습니다.

function showLayer(id) {
 document.getElementById(id).style.display = "block";
 return true;
}
자바스크립트의 편리한 점이자 문제점은 같은 이름의 펑션을 정의하면 나중에 정의된 내용으로 덮어씌워져 버린다는 건데요, 이걸 한 번 더 이용해서 위의 두 펑션이 공존할 수 있는 형태로 showLayer를 재정의했어요.

function showLayer(id, value) {
 document.getElementById(id).style.display = "block";
 var ele = document.getElementById(id);
 if (ele.style.visibility) {
  ele.style.visibility = value;
 }
 return true;
}
자 그럼 최종적인 수정.
티스토리의 스킨 수정에서 UNIQLOCK를 달 때에는 다음과 같이 스크립트를 붙이시면 돼요.
<script type="text/javascript" src="http://www.uniqlo.jp/uniqlock/user/js/고유ID.js"></script>
<script type="text/javascript">
function showLayer(id, value) {
 document.getElementById(id).style.display = "block";
 var ele = document.getElementById(id);
 if (ele.style.visibility) {
  ele.style.visibility = value;
 }
 return true;
}
</script>
그러면 제 블로그의 오른쪽 상단에 있는 것 처럼 UNIQLOCK도 잘 나오고 카테고리도 이상이 없게 쓸 수 있게 돼요 :D

덧붙이자면, 바로 이런 문제가 자바스크립의 치명적인 문제가 아닐까 싶어요.
이 문제를 해결하려면 티스토리 정도로 범용적인 서비스의 경우 반드시 서비스에서 공통적으로 사용하는 스크립트 코드들을 클래스화 하여 네임스페이스 때문에 생기는 문제가 없도록 해야 할 거에요.

그리고 UNIQLOCK처럼 어디에나 붙여서 쓸 수 있도록 하는 스크립트도 마찬가지로 클래스화 하여 다른 서비스에 영향을 주지 않도록 해야겠죠.

자바스크립트로 클래스를 만들어 쓰는 것은 자바 스크립트를 상당히 잘 하시는 분들도 그 필요성을 잘 이해를 못하는 경우가 많은 것 같아요. 그리고 충분히 알고 있다고 해도 잘 설계되지 않은 자바스크립트 클래스는 그렇지 않은 일반 함수보다 훨씬 디버깅하기 어렵다는 문제도 있죠.

VS 2008에서는 자바스크립트 클래스에 대한 인텔리센스나 디버깅을 지원한다는데 과연 어느 수준으로 될지는 모르겠지만 이런저런 문제로 저는 자바스크립트를 기피하는 편이에요 :(
신고
Posted by gongdo
후우... 이걸 몰라서 헤맨 시간을 생각하면 안습.

CImageList의 Create 메소드에서 다음과 같이 사용.

CImageList img;
img.Create(16, 16, ILC_COLOR|ILC_MASK, 1, 1);

중요한건 ILC_MASK!!
MASK가 빠지면 바탕색이 기본 BackGround색인 검정색이 됨.
신고
Posted by gongdo
TAG 디버깅
▶ 문제 코드
[환경]
OS : Windows 98
Language : Visual Basic 6.0 SP6
참고 : Paul Caton의 Self-SubClassing 기법(http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=54117&lngWId=1)

[소스 코드]
// 상세 생략 //
VB폼의 hWnd를 넘겨서 Subclass_Start()을 호출하여 서브클래싱을 시작하고
Subclass_AddMsg()로 몇 가지 메시지를 추가한 후 Subclass_Stop()을 호출.

▶ 문제점
- Windows 2000, XP 등 에서는 전혀 문제가 없지만 같은 코드를 Windows 98에서 실행할 경우 APP가 완전히 종료된 후 Memory Access Violation이 발생함
- APP 자체의 동작이나 서브 클래싱은 모두 정상적으로 작동하나 APP가 종료되는 시점에서 치명적으로 보기 좋지 않은 메시지를 보여주므로 문제.
- VB폼의 hwnd가 아닌 CreateWindow()등의 API로 생성한 윈도에서는 문제가 발생하지 않는 것으로 보임(정확하진 않음)

▶ 해결 과정
시도1 : 복잡한 서브 클래싱 과정을 최소로 줄여 SubClass_Start(), Stop()만 호출하여 테스트
여전히 같은 증상 발생.

시도2 : 라인 단위의 길고 지루한 트레이스를 통해 정상적으로 실행되지 않은 코드가 있는지 하나하나 체크... 별 다른 이상은 없음.

시도3 : 내부적으로 사용되는 GlobalAlloc(), VirtualProtect(), GlobalFree() 등의 동작 체크, 이상 없음.

시도4 : Paul Caton의 새 업데이트 없는지 확인. 없음.

시도5 : Self-SubClass 자체의 문제가 있다고 판단하고 다른 코드로 교체.
- 대체할 코드로 역시 Paul Caton이 작성한 WinSubHook.tlb 모듈을 사용.
- WinSubHook.tlb는 Self-SubClass에 비해 디자인 타임 의존성이 추가된다는 단점이 있지만 소스 코드는 훨씬 단순화 되므로 TLB 관리만 잘 한다면 큰 문제가 없을 것으로 생각됨.
- 같은 동작을 하는 코드를 WinSubHook TLB의 iSubClass 인터페이스를 통하여 구현, 2000, 98 모두 잘 동작하고 Access Violation도 발생하지 않음.

▶ 정리
- Paul Caton의 Self-SubClass 기법은 98에서 약간의 문제가 있는 것으로 판단됨.
- vbAccelerator.com에 올라온 Paul Caton의 WinSubHook TypeLibrary로 교체하여 해결함.
링크 : TLB 다운로드(http://www.vbaccelerator.com/home/VB/Type_Libraries/WinSubHook/article.asp)
WinSubHook 예제 및 설명(http://www.vbaccelerator.com/home/VB/Code/Libraries/Subclassing_and_Hooking_with_Machine_Code_Thunks/article.asp)
신고
Posted by gongdo

▶ 문제 코드
[환경]
OS : Windos 2000, 98(VMWare)
Language : Visual Basic 6.0 SP6
참고 : 순수 Win32 API 코드이므로 다른 언어에서도 같은 증상이 있을 것이라고 생각됨

[소스 코드]

▼ 소스코드 보기

▶ 문제점
- 같은 머신 상에서 시리얼 포트 체크를 위해 CreateFile()을 호출할 때 Windows 2000, XP일 경우 정상적인 핸들을 반환하였으나 Windows 98에서는 완전히 같은 코드로도INVALID_HANDLE_VALUE를 반환함.

▶ 해결 과정
시도1 : 일단 API 레퍼런스를 참고하여 의심되는 파라미터를 변경해 봄.

▼ CreateFile 정보

여전히 같은 증상, 시리얼 통신과 관련된 어떤 파라미터나 플래그 값으로도 같은 증상

시도2 : 구글링으로도 정확히 같은 증상은 없고 비슷하거나 반대의 케이스는 몇몇 보임
시도3 : 고심중 언뜻 스치고 지나간 생각, Win98은 SECURITY_ATTRIBUTES를 사용할 수 없다!!
따라서 CreateFile()에서 lpSecurityAttributes에 NULL을 주면 해결되지 않을까...
그런데 VB의 표준 CreateFile() 선언에서는 lpSecurityAttributes가 Byref로 잡혀있어서 NULL을 줄 수 없었던 것.
CreateFile() 선언은 그대로 두고 NULL 파라미터를 줄 수 있는 CreateFileNull()이란 이름으로 따로 선언하고 lpSecurityAttributes에 VB에서의 NULL인 0&를 주었더니 아무 문제 없이 해결됨.

Private Declare Function CreateFile Lib "kernel32.dll" Alias "CreateFileA" _
  (ByVal lpFileName As String, _
  ByVal dwDesiredAccess As Long, _
  ByVal dwShareMode As Long, _
  ByRef lpSecurityAttributes As SECURITY_ATTRIBUTES, _
  ByVal dwCreationDisposition As Long, _
  ByVal dwFlagsAndAttributes As Long, _
  ByVal hTemplateFile As Long) As Long

- 위에서 굵게 표시한 부분을 다음과 같이 수정
▶ Byval lpSecurityAttributes As Long
- CreateFile을 호출 할 때 SECURITY_ATTRIBUTES 구조체를 인수로 줬던 부분을 0&로 수정


▶ 정리
- 이 외에도 Win98에서 security_attributes를 요구하는 API를 쓸때는 각별한 주의가 필요함.
- 수정된 완전한 소스 코드

▼ 소스코드 보기

신고
Posted by gongdo


티스토리 툴바