전부는 아니지만 대부분의 폼 매니저 루틴들은 오브젝트 아이디보다는 오브젝트 인덱스를 요구한다. 일반적인 에러들은 아이디에서 인덱스로 컨버트하는 것을 잊어버리는 것이다. 여기 컨버트에 실패하는 잘못된 코드가 있다.
myList = (ListPtr) FrmGetObjectPtr(form, MainPeopleList); // 나쁨
이 상황을 제대로 처리하기 위한 올바른 방법은 다음과 같다.
myList = (ListPtr) FrmGetObjectPtr(form, FrmGetObjectIndex(form, MainPeopleList)); // 좋음
하나의 오브젝트 인덱스는 리스트에서 오브젝트들의 0....순으로 이어지는 범위에 있는 숫자이다. 따라서 그것은 일반적으로 작은 수이다. 반대로 오브젝트 아이디는 더 큰 숫자이다(일반적으로 1000보다 큼). 컨버전하는 것을 잊어버리는 사람들이 일반적으로 보게 되는 에러는 'index out of range: 1024'와 같은 것일 것이다. 인덱스에 대해 큰 수를 봤을 때 인덱스보다는 ID를 패스했다는 것이 중요한 실마리가 된다.
object ID나 object index 둘다 Ulnt16 type이 컴파일러에서 처리할 수 없기 때문에 나쁘게 만든다.
어떤 이벤트가 FrmHandleEvent에 의해 자동적으로 핸들링되는지 잊어버리는 것은 쉽다. 결과적으로 적절하지 못한 방법으로 true/false를 리턴하면 문제가 발생할 것이다. 이러한 상황은 이벤트 핸들러가 FrmDispatchEvent로부터 호출될때 발생한다. 만약 루틴이 false를 리턴하면 이벤트는 FrmHandleEvent으로 패스될 것이다. 어떤 이벤트가 개입되었느냐에 따라 그 시점에서 문제가 발생할 수도 있다. FrmHandleEvent은 특정 이벤트를 디폴드로 핸들링할 것이고 어느 이벤트가 디폴트 핸들링을 갖고 있는지 그렇지 않은지는 여러분에게 달려있다. 이것이 이벤트 핸들러로부터 true/false로 정확하게 리턴할 수 있는 유일한 방법이다.
여기 false를 리턴하는데 필요한 몇 가지 이벤트가 있다.
여러분도 짐작하듯이 디폴트 프로세싱이 발생하지 않도록 true를 리턴할 시기가 몇 번 있다. PopSelectEvent가 좋은 예이다. 만약 일반적인 발행 루틴을 갖고있고 NULL을 LstSetListChoices으로 패스했다면 true를 리턴해야 한다. True가 없다면 디폴트 핸들링은 NULL 배열로부터 텍스트 읽기를 시도할 것이다.
물론 그와 같은 상황에서 CtlSetLabel을 사용해 컨트롤 라벨을 업데이트 하는 것은 여러분에게 달려있다. 이때 여러분은 다음과 같이 질문할 수도 있다. "그와 같은 경우에 사용할 올바른 텍스트는 무엇인가?" 대답은 여러분이 발행할 루틴에 있다. 그 안에 있는 텍스트를 얻기 위한 몇 가지 방법을 이미 알고있으므로 같은 방법을 사용해라.
윈도우에서 등록된 컨디트(conduit)는 핸드헬드에서 같은 생성자 ID를 가지고 있는 애플리케이션이 없는 한 동기화 기간 동안 호출되지 않을 것이다. 핸드헬드에 성자 ID를 가지고 있는 데이터베이스가 있아는 것만으로는 충분하지 않다. 실질적인 애플리케이션이 필요하다. 컨디트가 항상 실행되는 Mac OS에서는 이것은 사실이 아니며 단지 상황을 흥미롭게 만들어가는 것뿐이다.
만약 항상 실행할 컨디트가 없다면 단지 컨디트를 실행하도록 유도하기 위해 존재하는 소형 애플리케이션을 만들어야 한다. 만약 유저가 그것을 보지 않기를 원한다면 항상 볼 수 없는 비트로 설정해놓을 수도 있다.
테스트를 도울 간단한 트릭이 있다. 여러분은 컨디트를 생성자 calc(계산기)로 등록할 수 있다. 그 애플리케이션은 항상 거기에 있으면서 컨디트를 실행하게 할 것이다. 그렇지만 최종 컨디트를 위해 생성자를 바꾸어 주어야 함을 기억해야 한다. 그리고 탑재된 컨디트에 대해서는 절대 calc를 사용할 수 없다.
표준 C 라이브러리를 이용할 수 있음에도 불구하고 일반적으로 잘 사용되지는 않는다. 대신 표준 C 루틴과 비슷한 Palm-OS용 API를 사용한다. Palm-OS 루틴을 선호하는 두 가지 이유는 다음과 같다.
표 1: 표준 C 루틴에 대한 Palm OS 루틴
| 표준 C루틴 | Palm OS루틴 | 부가 정보 |
| strlen | StrLen | . |
| strcpy | StrCopy | . |
| strncpy | StrNCopy | 여분의 널(null) 종결자와 함께 패딩하지 말 것. |
| strcat | StrCat | . |
| strncat | StrNCat | 마지막 매개변수는 복사할 문자의 숫자가 보다는 널 종결자를 포함한 스트링의 총 길이이다. 소스 스트링이 비어있다고 해도 여분의 널 종결자를 덧붙이지 말 것. |
| strcmp | StrCompare | . |
| strncmp | StrNCompare | . |
| itoa | StrIToA | . |
| strchr | StrChr | . |
| strstr | StrStr | . |
| sprintf | StrPrintF | sprintf의 한정된 서브세트 예를 들어 no %f. |
| svprintf | StrVPrintF | sprintf의 한정된 서브세트 예를 들어 no %f. |
| malloc | MemPtrNew | . |
| free | MemPtrFree | . |
| memmove | MemMove | . |
| memset | MemSet | 경고: 마지막 두 매개변수는 개정되었음. |
| memcmp | MemCmp | . |
리스트들이 스스로 lstSelectEvent를 생성함에도 불구하고 팝업은 실행되지 않는다. 대신 그것들은 popSelectEvent를 생성한다.
유저가 팝업 트리거로부터 아이템을 선택할때 어떻게 말해야 될지를 모르겠다면 여러분은 이와 같은 문제를 가지고 있는 것이다. lstSelectEvent에 대한 코드는 운영체제가 popSelectEvent을 대신 전달하기 때문에 실행되지 않는다.
폼의 첫번째 호출을 FrmDrawForm로 하기 전에 폼에서 어떤 것도 그릴 수 없는지에 대한 이유는 다음과 같다.
Palm OS 3.5이상에서 버그들은 필드를 포커스하는 것과 관련하여 존재했다. 만약 첫번재 호출로 FrmDrawForm을 하기 전에 FrmSetFocus을 호출하면 삽입 필드는 포커스된 필드에 나타나지 않을 것이다. 이런 문제를 처리하기 위해 FrmDrawForm의 첫번째 호출 후에 FrmSetFocus를 호출해야 한다.
Palm OS 3.5이상에서 버그가 수정되었음에도 불구하고 버그는 FrmDrawForm을 첫번째로 호출 한 후 FrmSetFocus을 계속해서 호출하는데 영향을 미치지 않는다.
라벨이라는 단어는 품에서 실행되어 질때 두 가지 다른 인스턴스에서 사용된다. 첫번째 용도는 폼과 관련있는 것으로 스스로 라벨을 가질 수 있다(예를 들어 특정 폰트로 어떤 지역에 있는 텍스트). 두 번째 용도는 컨트롤 매니저에 의한 것으로 라벨이 컨트롤 할 때 사용된다. 이 용도는 컨트롤을 가질때 사용되는데 컨트롤의 텍스트를 변경하기 위하여 컨트롤 매니저 루틴인 CtlSetLabel을 사용하게 될 것이다.
그외의 경우(콘트롤이 없는 옛날 라벨을 가지고 있을때)에서는 FrmCopyLabel을 사용한다.
대부분의 Palm OS 프로그래머들은 Palm OS 플랫폼에서 C 프로그매밍을 배우려는 것이 상당히 어렵다고 말한다. 만약 여러분이 능숙한 C 프록래머가 아니라면 단순한 환경에서 프로그래밍 언어를 배우는 것이 더 쉬울 것이다. C 언어를 배우기 위한 방법으로 CodeWarrior University라는 무료 학습 사이트의 'Learn Programming with C'라는 목록에서 프로그래밍 하는 방법과 C를 사용하는 방법에 대해 배울 수 있을 것이다.
POSE (Palm OS Emulator)와 Debug ROMs은 핸드헬드에서는 인지하지 못하는 많은 에러를 잡아내는 강력한 디버깅 조합을 만들어 낸다. Palm OS Developers site에서 해당하는 도구를 다운 받을 수 있다.
Palm OS에 대한 엄청난 정보를 가지고 있지만 POSE는 Palm OS 디바이스의 하드웨어를 에뮬레이트 한다. 함수 호출, 메모리 저장이나 로드, 레지스터 액세스, 액세스를 인정하는 검공기 등을 볼 수 있다.
Debug ROMs은 Palm Os APIs가 실제적인 디바이스인 ROM에서 추가적인 체크를 하게 한다. 테스팅과 디버깅은 POSE와 Debug ROMs를 항상 함께 사용하는 것으로 시작해야 한다.
만약 이 도구를 사용하는 동안 에러가 나타난다면 그것을 수정해야 한다. 그것은 실제적인 디바이스에서 계속해서 나타날 문제가 될 수도 있으며 잠깐 나타났다 없어질 문제일 수도 있다. 또한 오늘날의 디바이스에서는 문제되지 않을 수도 있지만 미래의 디바이스에서는 문제가 될 수도 있기 때문에 에러는 항상 수정해 주는 것이 좋다.
StopApplication()에서 FrmCloseAllForms();와 FrmSaveAllForms();를 호출하도록 하자. 이걸 빼 먹었으면 memory leak이 생긴다.
---
DeleteMe koreapalm.com 이라는데서 퍼온 문서인데 누가 작성했는지는 모르겠네요... 거기도 출처가 적혀 있지 않아서요. -- jmjeong