воскресенье, 26 сентября 2010 г.

Про Xcode

Программирование под мак похоже на изучение боевого икусства. После MS Visual Studio, Xcode - вызывает ассоциации аскетичности, минимализма... (как то все хреново тут...))))
Парадигма эппловской IDE, заключается в различных подходах. Все управление сосредоточено на хоткеях. Мощный фреймворк Cocoa, средства профайлинга, счетчики и утилиты, упрощающие жизнь рядовым разработчикам. И это работает.
Справка как ни странно подкачала, MSDN увы нормального нету. Есть гайды почитать можно для общего развития. В этой ситуации проще брать какой нибудь open source проект и смотреть как в нем сделаны те или иные вещи. Поскольку так или иначе, все общение с OS будет идти через Cocoa-Objective-C (можно прожить и с СoreFundation, Carbon deprecated - C фрэймворк).
Отладчик, заслуживает отдельных каментов. Глючит часто и не корректно показывает данные. Проще и нагляднее использовать трэйсирование, логирование или вывод дебаг данных прямо в программе.

В целом после некоторого времени общения с XCode, можно говорить о том, что разработка в ней, ни чем не отличается от разработки в других средах. Сама IDE, прогрессирует семимильными шагами. В 4 версии обещают кучу улучшений и доработок.

суббота, 18 сентября 2010 г.

Читаем книги на iphone.

После покупки iphone, задался вопросом чем читать книги на iphone. После продолжительного поиска остановился на Stanza. На данный момент лучшее решение для чтение художественных книг на iphone

Плюсы 

+ Бесплатная
+ Простое управление с достаточным колличеством настроек ( цветовые схемы и etc. ), текст рисуется на всю область экрана, очень удобно.
+ Stanza Desktop бесплатная десктопная софтина с кучей настроек для конвертации кучи форматов в приемлимый для меня epub. Плюс возможность посмотреть как будет книга будет отформатирована под девайс.
( после общения с кучей дурацких онлайн конвертеров, от которых надо держаться подальше, ни один так называемый конвертер не смог приемлимо создать из html -> epub, вместо книг на выходе получались файлики по 37 kb. )
+ Добавление книг по прямой ссылке ( с Box.net не удалось скачать книгу, видимо у меня был фришных аккаунт, а там нельзя получать прямые ссылки )
+ Не ест трафик ( iBooks в этом плане напрягает, что при добавлении новой книги, обязательно что-то ищет в сети )
+ Быстро работает перелистывание на несколько страниц, загрузка книги с нуля для больших книг ( iBooks - на таких книгах, думает и лезет в сеть )

Минусы

- Нет смысла закачивать книги в формате PDF ( iBooks - идеальное решения для просмотра PDF )

вторник, 7 сентября 2010 г.

Dead Keys

«Мёртвые клавиши» (англ. dead keys) — клавиши на компьютерных клавиатурах или пишущих машинках, позволяющие изменить вид следующего вводимого символа. На печатных машинках нажатие на «мёртвую» клавишу ставит надстрочный символ, но не сдвигает каретку на следующий символ. На компьютерах нажатие «мёртвой» клавиши изменяет код следующего вводимого символа.

С вводом обычных символом все отлично для английского или русского языков. Пока вам не понадобится самому написать отработку ввода с клавиатуры для разнообразных языков (французский, языки Африки etc ).
á, é, í, ó, ú - примеры таких символов, которые вводятся из соотвествующих комбинаций на клавиатуре. Для стандартных контролов ввод таких символов сделан на уровне OS. Для самописных текстовых контролов, разумеется требуется свой обработчик сообщений.

Код для обработки таких символов ( проверено для французского языка ).

  1. WCHAR       DEAD_KEY;   
  2.    
  3. VOID OnKeyDown ( UINT Key )   
  4. {   
  5.     if (( Key >= 'A'     && Key <= 'Z'        ) ||    
  6.         ( Key >= '0'     && Key <= '9'        ) ||    
  7.         ( Key >= VK_OEM_1    && Key <= VK_OEM_3   ) ||    
  8.         ( Key >= VK_OEM_4    && Key <= VK_OEM_8   ) ||   
  9.         ( Key >= VK_NUMPAD0 && Key <= VK_DIVIDE ) )   
  10.     {   
  11.         WCHAR wKEY [ 3 ]    =   { L'\0', L'\0', L'\0' };   
  12.    
  13.         BYTE kbdState[256];   
  14.         ZeroMemory( kbdState, 256 );   
  15.    
  16.         GetKeyboardState ( kbdState );   
  17.    
  18.         WCHAR KeyboardState =   wKEY [ 0 ];   
  19.    
  20.         if ( 1 == ToUnicode ( Key, 0, kbdState, wKEY, 3, 0 ) )   
  21.         {   
  22.             if ( DEAD_KEY != L'\0' )    
  23.             {   
  24.                 WCHAR WCS_IN[3];   
  25.                 WCHAR WCS_OUT[3];   
  26.    
  27.                 WCS_IN[0] = wKEY[0];   
  28.                 WCS_IN[1] = DEAD_KEY;   
  29.                 WCS_IN[2] = L'\0';   
  30.    
  31.                 /* from accent char to unicode */   
  32.                 if ( FoldStringW ( MAP_PRECOMPOSED, WCS_IN, 3, WCS_OUT, 3 ) )   
  33.                 {   
  34.                     wKEY[0] = WCS_OUT[0];   
  35.                     wKEY[1] = WCS_OUT[1];   
  36.                     wKEY[2] = WCS_OUT[2];   
  37.                 }   
  38.             }   
  39.             else   
  40.             {   
  41.    
  42.             }   
  43.    
  44.             DEAD_KEY = L'\0';   
  45.         }   
  46.         else   
  47.         {   
  48.             DEAD_KEY            =   L'\0';   
  49.    
  50.             switch ( wKEY[0] )    
  51.             {   
  52.             case 0x5e:          /* circumflex */   
  53.                 DEAD_KEY = 0x302;  break;   
  54.             case 0x60:          /* grave accent */   
  55.                 DEAD_KEY = 0x300;  break;   
  56.             case 0xa8:          /* diaeresis */   
  57.                 DEAD_KEY = 0x308;  break;   
  58.             case 0xb4:          /* acute accent */   
  59.                 DEAD_KEY = 0x301;  break;   
  60.             case 0xb8:          /* cedilla */   
  61.                 DEAD_KEY = 0x327;  break;   
  62.             default:   
  63.                 DEAD_KEY    =   wKEY[0];   
  64.                 break;   
  65.             }   
  66.    
  67.             return;   
  68.         }                      
  69.    
  70.         wKEY [ 1 ]  =   L'\0';   
  71.    
  72.         CString String  =   CStringW ( wKEY );  //  нужная нам буква   
  73.     }   
  74. }  


Free 3d Screen Saver

Японские символы

Ввод иероглифов на на японском происходит либо через специальную клавиатуру (виртуальную), либо сочетанием из нескольких символов c обычной клавиатуры. Тут возникает вопрос, а как все это безобразие правильно отработать (при условии что у вас свой ввод данных идет, а не через стандартные контролы EditBox etc, в них по умолчанию с вводом все хорошо). Часть символов приходят от виртуальной клавиатуры. Ниже код для получения строки символов со специального окна ввода иероглифов.


  1. pragma once   
  2.        
  3. // - For East Asian languages such as Chinese, Japanese, Korean, and other languages with complex characters.    
  4. // - Input Method Editors (IME)    
  5.    
  6. // http://msdn.microsoft.com/en-us/library/ee419002(VS.85).aspx   
  7. // http://msdn.microsoft.com/en-us/library/dd318641(VS.85).aspx   
  8.    
  9. #include <Imm.h>   
  10.    
  11. #pragma comment ( lib, "imm32.lib" )   
  12.    
  13. class CIMEUIController   
  14. {   
  15. public:   
  16.        
  17.     CIMEUIController ()   
  18.     {   
  19.         m_bInitialized = false;   
  20.     }   
  21.    
  22.     ~CIMEUIController ()   
  23.     {   
  24.         Uninitialize ();   
  25.     }   
  26.    
  27.        
  28.     bool Initialize( HWND hWND )   
  29.     {   
  30.         if ( m_bInitialized )   
  31.             return true;   
  32.    
  33.         m_hWND = hWND;   
  34.        
  35.         return true;   
  36.     }   
  37.    
  38.     void Uninitialize()   
  39.     {   
  40.         if ( false == m_bInitialized )   
  41.             return;   
  42.            
  43.         m_bInitialized = false;   
  44.     }   
  45.    
  46.        
  47.     LPARAM ProcessMessage ( UINT uMsg, WPARAM wParam, LPARAM& lParam, WCHAR** ppIMEStr, LONG& IMEBytes )   
  48.     {   
  49.         switch ( uMsg )   
  50.         {   
  51.         case WM_IME_STARTCOMPOSITION:   
  52.             {   
  53.                
  54.             }   
  55.             break;   
  56.            
  57.         //    
  58.         case WM_IME_ENDCOMPOSITION:   
  59.             {   
  60.                 *ppIMEStr   =   NULL;   
  61.                 IMEBytes    =   0;   
  62.    
  63.                 HIMC hIMC = ImmGetContext ( m_hWND );   
  64.                 if ( hIMC )   
  65.                 {   
  66.                     LONG IMECursorBytes = ::ImmGetCompositionStringW ( hIMC,    
  67.                         GCS_RESULTSTR,   
  68.                         //GCS_RESULTREADSTR   
  69.                         NULL, 0 );   
  70.    
  71.                     DWORD Bytes = 0;   
  72.                     WCHAR* pIMEStr = new WCHAR [ IMECursorBytes + 1 ];   
  73.                     ::ZeroMemory ( pIMEStr, sizeof ( WCHAR ) * IMECursorBytes + 1 );   
  74.                        
  75.                     if ( pIMEStr )   
  76.                     {   
  77.                         if ( 0 != ::ImmGetCompositionStringW ( hIMC,    
  78.                             GCS_RESULTSTR,   
  79.                             //GCS_RESULTREADSTR,   
  80.                             pIMEStr, IMECursorBytes + 1 ) )    
  81.                         {   
  82.                             *ppIMEStr   =   pIMEStr;   
  83.                             IMEBytes    =   IMECursorBytes + 1;   
  84.                        
  85.                             ImmReleaseContext ( m_hWND, hIMC );   
  86.    
  87.                             return TRUE;   
  88.    
  89.                         }   
  90.                     }   
  91.    
  92.                     ImmReleaseContext ( m_hWND, hIMC );   
  93.                 }   
  94.             }   
  95.             break;   
  96.    
  97.         case WM_IME_NOTIFY:   
  98.             {   
  99.                 switch ( wParam )   
  100.                 {   
  101.                 case IMN_SETCONVERSIONMODE:   
  102.                 case IMN_SETOPENSTATUS:   
  103.                     break;   
  104.    
  105.                 case IMN_OPENCANDIDATE:   
  106.                 case IMN_CHANGECANDIDATE:   
  107.                     break;   
  108.                 }   
  109.             }   
  110.             break;   
  111.         }   
  112.    
  113.         return FALSE;   
  114.     }   
  115.    
  116.    
  117. private:   
  118.    
  119.     bool    m_bInitialized;   
  120.    
  121.     HWND    m_hWND;   
  122. };  


Free 3D Screen Saver