31.03.2008, 10:48 | #1 |
Участник
|
Создание буфера обмена на бездисковых станциях
Заполняю объект TextBuffer. Далее пытаюсь вставить сформированное значение в буфер обмена.
TextBuffer.toClipboard(); И вот тут "облом". Вставки не происходит по той причине, что буфера обмена не существует! Прямая попытка открытия буфера обмена через команду WinApi::openClipboard(0) Оканчивается неудачей. Происходит это, как правило, при первом открытии терминального сеанса. Т.е. пользователь только включил компьютер. Причем, массовый характер это имеет только на бездисковых станциях. В "обычной" терминальной сессии такое тоже случается, но значительно реже. Лечится все явной инициализацией буфера обмена примерно таким способом: - Открыть блокнот (notepad.exe) - Ввести в него какой-либо "мусор" - Выделить фрагмент и загнать его в буфер обмена по Ctrl+C До закрытии сессии - проблема снимается. Существует ли какой-либо способ принудительной инициализации буфера обмена? Как его можно "пнуть" программно для инициализации? Axapta 2.5 SP3 |
|
02.04.2008, 15:34 | #2 |
Участник
|
Вроде бы, решение найдено. Раз надо создать буфер обмена, а прямые API-функции с этим не справляются, то и надо переложить эту работу "на плечи" того приложения, которое может это сделать. Например, MS Excel.
X++: ComExcelDocument_RU excel; COM comRange ; excel = new ComExcelDocument_RU(); excel.newFile("",true); comRange = excel.findRange("A1"); comRange.value2("Инициализация буфера обмена"); comRange.copy(); Не скажу, что эта операция на 100% исключила возникновение ошибки копирования в буфер обмена, но теперь это не постоянная головная боль, а отдельные "случайные" эпизоды. Да, если копирование происходит в методе класса ComExcelDocument_RU, то там все проще. Ведь Range определяется там же, в методе вставки. Вот непосредственно перед вставкой данных и надо в найденный Range вставить любое значение и выполнить метод range.copy(). |
|
02.04.2008, 17:15 | #3 |
Пенсионер
|
А если попробовать через, например:
X++: TextBuffer tb = new TextBuffer(); ; tb.appendText("qwerty"); tb.toClipboard();
__________________
Законы природы еще никто не отменял! А еще у меня растет 2 внучки!!! Кому интересно подробности тут: http://www.baby-shine.com/ |
|
02.04.2008, 17:24 | #4 |
Участник
|
Самое начало сообщения:
Цитата:
Заполняю объект TextBuffer. Далее пытаюсь вставить сформированное значение в буфер обмена.
TextBuffer.toClipboard(); И вот тут "облом". Вставки не происходит по той причине, что буфера обмена не существует! |
|
03.04.2008, 07:32 | #5 |
Пенсионер
|
Извиняюсь был не внимателен :(
У меня вопросик есть по этому поводу, просто интересно стало, в функцию WinApi::openClipboard(0) Вы передаете "0" а может всетаки передать хендлер текущего окна, как написано в MSDN?
__________________
Законы природы еще никто не отменял! А еще у меня растет 2 внучки!!! Кому интересно подробности тут: http://www.baby-shine.com/ Последний раз редактировалось blokva; 03.04.2008 в 07:43. |
|
03.04.2008, 10:20 | #6 |
Участник
|
Может, попробовать посылать сообщение WM_COPY какому-либо окну?
__________________
Axapta v.3.0 sp5 kr2 |
|
03.04.2008, 10:42 | #7 |
Участник
|
Цитата:
Только это все не спасает. Собственно, запись в буфер обмена используется для последующей вставки в Excel через pastSpecial(). Так вот, никакие манипуляции с буфером обмена не дают гарантии, что все будет работать так как и задумывалось. Например, в коде может успешно пройти команда WinApi::openClipboard(0). Более того, может даже успешно удастся записать информацию в буфер обмена при помощи API-функции SetClipboardData(). Но! TextBuffer.toClipboard() все равно ничего не запишет в буфер! Ошибка "плавающая". Может произойти на любом этапе инициализации и формирования буфера обмена, если это происходит при помощи API-функций или методов класс TextBuffer. А вот использование методов работы с буфером собственно Excel (фактически, того приложения для которого мне и надо сформировать буфер) дает достаточно высокую вероятность успеха. |
|
03.04.2008, 10:44 | #8 |
Участник
|
|
|
03.04.2008, 11:15 | #9 |
Участник
|
Ну, на самом деле никто не мешает создать его
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); } } PS и никаких заморочек с раскладкой клавиатуры
__________________
Axapta v.3.0 sp5 kr2 Последний раз редактировалось AndyD; 03.04.2008 в 11:20. |
|
03.04.2008, 11:41 | #10 |
Участник
|
Да, это была одна из первых моих идей. Раз манипуляции с блокнотом помогают, то почему бы не сделать этого программно. Но использование собственно Excel - проще.
Впрочем, буду иметь такой вариант в виду, если копирование содержимого ячейки Excel не поможет. Пока за сутки никаких претензий от польователей не поступало. |
|
Теги |
ax2.5 |
|
Похожие темы | ||||
Тема | Ответов | |||
Размер буфера | 5 | |||
CRM создание писем и их рассылка - в чем трабл? | 9 | |||
Импорт из буфера | 13 | |||
Сохранение/восстановление буфера обмена | 0 | |||
Права на создание шаблонов записей | 1 |
|