AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск Все разделы прочитаны

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 31.03.2008, 10:48   #1  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,651 / 1158 (42) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Создание буфера обмена на бездисковых станциях
Заполняю объект TextBuffer. Далее пытаюсь вставить сформированное значение в буфер обмена.

TextBuffer.toClipboard();

И вот тут "облом". Вставки не происходит по той причине, что буфера обмена не существует!

Прямая попытка открытия буфера обмена через команду

WinApi::openClipboard(0)

Оканчивается неудачей.

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

Лечится все явной инициализацией буфера обмена примерно таким способом:

- Открыть блокнот (notepad.exe)
- Ввести в него какой-либо "мусор"
- Выделить фрагмент и загнать его в буфер обмена по Ctrl+C

До закрытии сессии - проблема снимается.

Существует ли какой-либо способ принудительной инициализации буфера обмена? Как его можно "пнуть" программно для инициализации?

Axapta 2.5 SP3
Старый 02.04.2008, 15:34   #2  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,651 / 1158 (42) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Вроде бы, решение найдено. Раз надо создать буфер обмена, а прямые API-функции с этим не справляются, то и надо переложить эту работу "на плечи" того приложения, которое может это сделать. Например, MS Excel.

X++:
    ComExcelDocument_RU     excel;
    COM                     comRange
    ;

    excel = new ComExcelDocument_RU();
    excel.newFile("",true);

    comRange = excel.findRange("A1");
    comRange.value2("Инициализация буфера обмена");
    comRange.copy();
Т.е. копируем в буфер обмена содержимое не пустой (в смысле, заполненной) ячейки Excel, что, собственно, и приводит к инициализации буфера обмена.

Не скажу, что эта операция на 100% исключила возникновение ошибки копирования в буфер обмена, но теперь это не постоянная головная боль, а отдельные "случайные" эпизоды.

Да, если копирование происходит в методе класса ComExcelDocument_RU, то там все проще. Ведь Range определяется там же, в методе вставки. Вот непосредственно перед вставкой данных и надо в найденный Range вставить любое значение и выполнить метод range.copy().
Старый 02.04.2008, 17:15   #3  
blokva is offline
blokva
Пенсионер
Аватар для blokva
SAP
NavAx Club
 
743 / 167 (7) ++++++
Регистрация: 04.06.2003
Адрес: Беларусь
А если попробовать через, например:
X++:
TextBuffer          tb = new TextBuffer();
;
tb.appendText("qwerty");
tb.toClipboard();
__________________
Законы природы еще никто не отменял!
А еще у меня растет 2 внучки!!! Кому интересно подробности тут:
http://www.baby-shine.com/
Старый 02.04.2008, 17:24   #4  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,651 / 1158 (42) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Самое начало сообщения:

Цитата:
Заполняю объект TextBuffer. Далее пытаюсь вставить сформированное значение в буфер обмена.

TextBuffer.toClipboard();

И вот тут "облом". Вставки не происходит по той причине, что буфера обмена не существует!
Старый 03.04.2008, 07:32   #5  
blokva is offline
blokva
Пенсионер
Аватар для blokva
SAP
NavAx Club
 
743 / 167 (7) ++++++
Регистрация: 04.06.2003
Адрес: Беларусь
Цитата:
Сообщение от Владимир Максимов Посмотреть сообщение
Самое начало сообщения:
Извиняюсь был не внимателен :(

У меня вопросик есть по этому поводу, просто интересно стало, в функцию WinApi::openClipboard(0)
Вы передаете "0" а может всетаки передать хендлер текущего окна, как написано в MSDN?
__________________
Законы природы еще никто не отменял!
А еще у меня растет 2 внучки!!! Кому интересно подробности тут:
http://www.baby-shine.com/

Последний раз редактировалось blokva; 03.04.2008 в 07:43.
Старый 03.04.2008, 10:20   #6  
AndyD is offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2,560 / 2476 (88) +++++++++
Регистрация: 20.08.2005
Может, попробовать посылать сообщение WM_COPY какому-либо окну?
__________________
Axapta v.3.0 sp5 kr2
Старый 03.04.2008, 10:42   #7  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,651 / 1158 (42) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Цитата:
Сообщение от blokva Посмотреть сообщение
У меня вопросик есть по этому поводу, просто интересно стало, в функцию WinApi::openClipboard(0)
Вы передаете "0" а может всетаки передать хендлер текущего окна, как написано в MSDN?
Ну, в MSDN написано также, что можно передавать значение NULL. Т.е. в синтаксисе Axapta значение 0 как раз и эквивалентно использованию NULL.

Только это все не спасает. Собственно, запись в буфер обмена используется для последующей вставки в Excel через pastSpecial(). Так вот, никакие манипуляции с буфером обмена не дают гарантии, что все будет работать так как и задумывалось.

Например, в коде может успешно пройти команда WinApi::openClipboard(0). Более того, может даже успешно удастся записать информацию в буфер обмена при помощи API-функции SetClipboardData(). Но! TextBuffer.toClipboard() все равно ничего не запишет в буфер!

Ошибка "плавающая". Может произойти на любом этапе инициализации и формирования буфера обмена, если это происходит при помощи API-функций или методов класс TextBuffer.

А вот использование методов работы с буфером собственно Excel (фактически, того приложения для которого мне и надо сформировать буфер) дает достаточно высокую вероятность успеха.
Старый 03.04.2008, 10:44   #8  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,651 / 1158 (42) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Цитата:
Сообщение от AndyD Посмотреть сообщение
Может, попробовать посылать сообщение WM_COPY какому-либо окну?
Кроме собственно Axapta и экземпляра Excel (в не видимом режиме) в этот момент нет открытых окон.
Старый 03.04.2008, 11:15   #9  
AndyD is offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2,560 / 2476 (88) +++++++++
Регистрация: 20.08.2005
Ну, на самом деле никто не мешает создать его

X++:
static void Copy2Clipboard(Args _args)
{
    #winapi
    #define.GWL_HINSTANCE       (-6)
    #define.WM_COPY             (0x0301)
    #define.EM_SETSEL           (0x00B1)
    int     clipWnd;
    int     hInstance = winapi::getWindowLong(infolog.hWnd(), #GWL_HINSTANCE);
    dll dll = new dll("user32");
    dllfunction CreateWindow = new dllfunction(dll, "CreateWindowExA");
    str text = "oit weroip t437892573\r\nosfiduasdf7ds98a0\r\lkfdsalk\tgfsdkljglksdfjglsfd;";
    ;
    CreateWindow.arg(ExtTypes::DWord, ExtTypes::String, ExtTypes::String, ExtTypes::DWord, ExtTypes::DWord, 
        ExtTypes::DWord, ExtTypes::DWord, ExtTypes::DWord, ExtTypes::DWord, ExtTypes::DWord, 
        ExtTypes::DWord, ExtTypes::DWord);
    CreateWindow.returns(ExtTypes::DWord);
    clipWnd = CreateWindow.call(0, "EDIT", "AxTSClipboard",  #WS_CHILD, 0, 0, 10, 10, infolog.hWnd(), 0, hInstance, 0);
    if (clipWnd)
    {
        winapi::setWindowText(clipWnd, text);
        winapi::sendMessageEx(clipWnd, #EM_SETSEL, 0, -1);
        winapi::sendMessageEx(clipWnd, #WM_COPY, 0, 0);
        winapi::destroyWindow(clipWnd);
    }
}
Т.е. с помощью такого подхода можно вообще отказаться от использования TextBuffer

PS и никаких заморочек с раскладкой клавиатуры
__________________
Axapta v.3.0 sp5 kr2

Последний раз редактировалось AndyD; 03.04.2008 в 11:20.
Старый 03.04.2008, 11:41   #10  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,651 / 1158 (42) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Да, это была одна из первых моих идей. Раз манипуляции с блокнотом помогают, то почему бы не сделать этого программно. Но использование собственно Excel - проще.

Впрочем, буду иметь такой вариант в виду, если копирование содержимого ячейки Excel не поможет. Пока за сутки никаких претензий от польователей не поступало.
Теги
ax2.5

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Размер буфера MironovI DAX: Администрирование 5 20.03.2009 11:52
CRM создание писем и их рассылка - в чем трабл? ShadowFromXZone DAX: Функционал 9 17.06.2008 16:51
Импорт из буфера vey DAX: Программирование 13 27.06.2006 16:46
Сохранение/восстановление буфера обмена Peter Savintsev DAX: База знаний и проекты 0 01.04.2006 12:59
Права на создание шаблонов записей linney DAX: Администрирование 1 18.02.2005 15:08
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 21:52.
Powered by vBulletin® v3.8.5. Перевод: zCarot
Контактная информация, Реклама.