вторник, 19 апреля 2011 г.

Нотификация между потоками и GUI ( NSNotificationCenter )

Используете потоки для выполнения нужной работы. Хотите использовать нотификацию о каких то событиях между потоками ( для связи с тем же GUI, выброс ошибок, передача данных и etc ). В этом случае нужно корректно отсылать такие сообщения в контексте главного потока. Проблема может проявится не сразу, в не ожиданный момент.

  1. #pragma mark post thread safe notifity messages   
  2. - (void) sendErrorNotification : (NSString *) message   
  3. {   
  4.   [ [ NSNotificationCenter defaultCenter ] postNotificationName : @"NotifyUser"   
  5.                                                          object : message ];   
  6. }   
  7.    
  8. - (void) postSafeNotifityMessage : (NSString *) message   
  9. {   
  10.        [ self performSelectorOnMainThread : @selector(sendErrorNotification:)   
  11.                                withObject : message     
  12.                             waitUntilDone : NO ];   
  13. }   
  14.    
  15. Пример посылки сообщения об ошибки сети.   
  16.    
  17. - (void) connection : (NSURLConnection *) connection didFailWithError : (NSError *) error   
  18. {   
  19.        [ self postSafeNotifityMessage : [ error localizedDescription ] ];   
  20. }   

воскресенье, 13 февраля 2011 г.

Размышления о mercurial

В силу некоторых обстоятельств, перевели проекты на mercurial.

Первое - сложности при развертываниее сервера для распределенной команды разработчиков. Поэтому сервер имелся только у одного человека.
Второе - у кого нету сервера, создавали свои псевдо мини сервера (отедельны папки).
Было еще несколько проблем, которые доставляли мелкие не удобства при работе с репозиториями.

Выбор пал на mercurial. Децентрализованя система хранения исходников проектов. Сервер в данном случае не нужен. Очень удобно когда можно работать без доступа к центральному репозиторию или когда есть возможность делиться своими экспериментальными ветками с другими участниками разработки.

При разработке, делаю много мелких изменений в кодобазе. Поэтому актуально иметь несколько веток на локальной машине для промежуточных комитов. Почитать про mercurial можно на хабре, там Джоэль очень подробно описывает как работать с ветками, мержить их и т.д.


Бесплатный клиент для mac os x MacHG

На данный момент, переход с svn на mercurial, можно считать успешным.

PS. С другой стороны, если у команды разработчиков есть возможность использовать проверенный годами SVN, то было бы глупо откзываться от него ( если еще они сидят в одной комнате, то переход ня mercurial -> just for fun ).

пятница, 21 января 2011 г.

Железяка Amazon Kindle 3 Wi-Fi

Перед Новым Годом решил себя побаловать электронной читалкой книг. Долго не думал выбрал Amazon Kindle 3 Wi-Fi. Цена у него оказалась ниже конкурентов, да и в сравнении с другими аналогами.. Девайс обошелся в 6500 рублей, доставка курьером в руки (купил на ebay.com у дяди, которые уже несколько тыщ распродал ).

Понравилось

- Удобная эргономика приятно держать в руках, небольшой вес
- Идеальный вариант для чтения художественной литературы
- Русский язык в коробке ( понимает русские тексты, плясать с бубном не пришлось )
- Три гига свободного места, в системе определяется как флэшка, достаточно для того что бы не парится. Закинул книгу и читаешь.
- Есть внутренний браузер ( мелочь а приятно )

С этим жить можно

- Коллекции - ручками придется рассортировать все книги закинутые на девайс в ручную, в виртуальные папки. Не так критично, но если у вас коллекция из нескольких сотен книг, потратите время на это дело.
- PDF на таком мелком экране нет смысла читать
- Нет поддержки карточек (SD например, для хранения библиотек)
- Механика кнопки reset имеет тенденцию большого люфта и щелкания 

Update (14.09.2011) 
Появился тут на днях kindle, который не видит книги прямым копированием из проводника или finder в маке на устройство книг. Желание разбираться с прошивками особо нету. Озадачился программой для с девайсом что бы было все включено.
Как закинуть книгу в kindle ? Используем программу Сalibre ( включает конвертер книг, синхронизацию с устройством, конвертация новостей из сети, управление коллекцией книг ). Программа бесплатная. Проверено работает как на mac os x так и на windows.

четверг, 23 декабря 2010 г.

Железяка тыррнет-центр ZYXEL NBG334W EE

Нужен был wi-fi по всей квартире, поэтому купил ZYXEL NBG334W EE ( Интернет-центр для подключения по выделенной линии Ethernet с точкой доступа Wi-Fi 802.11g и коммутатором Ethernet... бла бла))) Особо не выбирал что купить, взял то что попалось. После трех месяцев использования сие чудо. Вердикт утвердительный - "Пользоваться можно"

понравилось
+ удобное управление и настройка устройства через web- интерфейс 
+ wi-fi работает на отлично, с айфоном все на ура работает
+ решение из коробки, включил и работает
+ белый корпус ( мелочь а приятно )

очень не понравилось
- связка ADSL модем + желязяка - долгий старт ( от 5 до 10 минут )
- если используем uTorrent все отмирает, сказывается слабенькая начинка железяки


update(24.09.2011)
Обновляйте ваше устройство прошивкой - Микропрограмма версии 3.60(AMW.5)D0 для NBG334W EE. В этом случае решаются проблемы долгого старта и подключением по PPPoE.

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

Drag and Drop on a Mac

Отработка драга&дропа в маке банальна по своей сути, если известно что делать ).

Рассмотрим случай когда досточно простого переноса/добавление файлов, папки, диска в программу. Бонусом идет, что если мы переносим эти объекты на пиктограмму не запущенной еще программы, то используется тот же механизм (к примеру есть известная программа iPhoto, в нее можно закидывать фотки как папками, кучей файлов, отдельным файлом, так и переносм на пиктограмму).

Первое что нам понадобится, это подправить немного info.plist 

Information Property List -> добавляем Document types
В Document types -> Item -> Document OS Types
В Document OS Types ->
Item 0 = ****
Item 1 = fold (для папок и файлов)
Item 2 = disk (для дисков)
Можно выставить Role = Viewer.

Теперь добавим немного кода в класс-делегат (обычно это основной Controller к которому привязан View).

  1. - (NSDragOperation)draggingEntered:(id )sender   
  2. {   
  3.     // в зависимости от типа операции перенос, добавление etc.   
  4.     // будет у нас при драге на объекте значок   
  5.     return NSDragOperationLink;   
  6. }   
  7.    
  8. - (BOOL)prepareForDragOperation:(id )sender   
  9. {   
  10.     return YES;   
  11. }   
  12.    
  13. - (BOOL)performDragOperation:(id )sender   
  14. {   
  15.     NSPasteboard *pboard;   
  16.     NSDragOperation sourceDragMask;   
  17.           
  18.     sourceDragMask = [sender draggingSourceOperationMask];   
  19.     pboard = [sender draggingPasteboard];   
  20.           
  21.     if ([[pboard types] containsObject:NSFilenamesPboardType])   
  22.     {   
  23.         NSArray *files = [pboard propertyListForType:NSFilenamesPboardType];   
  24.           
  25.         // ... отрабатываем данные      
  26.           
  27.     }   
  28.           
  29.     return YES;   
  30. }  

пятница, 1 октября 2010 г.

Книги по Cocoa

Книги в переводе бестолковые. Откровенно говоря, очень слабые. Для тех кто знаком с ООП языками, не представляют особой ценности в плане новых концепций и знаний.

Аарон Хиллегасс
Программирование в среде Cocoa для Mac OS X


Марк Далримпл, Скотт Кнастер
Objective-C 2.0 и программирование для Mac


Несколько книг с более интересным содержанием на языке оригинала.

Learn Xcode Tools for Mac OS X and IPhone Development

Cocoa and Objective-C: Up and Running: Foundations of Mac, IPhone, and IPod ...

Learn Objective-C on the Mac

В дороге интересно почитать книжечки, но для работы совершенно не удобны. Гайды на сайте разработчиков от эпла, достаточно подробны Mac OS X Reference Library.

www.epicreal.com

воскресенье, 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

понедельник, 30 марта 2009 г.

Tips & tricks WinForms .NET 2

Перемещение окна за любое место

  1. const int WM_NCHITTEST = 0x84;   
  2. const int HTCAPTION = 2;   
  3. const int HTCLIENT = 1;   
  4.    
  5. protected override void WndProc(ref Message m)   
  6. {   
  7.        base.WndProc(ref m);   
  8.    
  9.        if (m.Msg == WM_NCHITTEST && (int)m.Result == HTCLIENT)   
  10.            m.Result = (IntPtr)HTCAPTION;   
  11. }