PowerBuilder FAQ

Как пронумеровать группы?
Как заставить powerbuilder интерпретировать динамически созданные скрипты?
Как определить размер объекта?
Как узнать: существует ли объект в библиотеках не вызывая LibraryDirectory?
Как скрестить PowerBuilder с Perl-ом?
Как сделать DDDW с параметром?
Как найти строку с определенными значениями в полях DW?
Как переретривить одну строку?
Как получить текстовое значение текущей строки в DDDW?
Как переключаться между раскладками клавиатуры?
Как двигаться по DW по Enter?
Как создавать ярлыки? (*.lnk)
Как в группе строки пересчитать?
Как в группе строки пронумеровать?
Как поставить pb без ASA?
Как узнать, что приложение запущено из среды разработки?
Как получать значения полей dw, в том числе, вычислимых?
Как отработать событие KeyPress на активном DWControle
Внешние функции
Использование стандартных функций C/C++
Глюки при импорте данных в dw, находящегося в querymode
Доступ ко вложенным отчетам в composite DW
Хранимые процедуры Oracle как источних данных для DW
Как избежать ошибок, связанных с разными разделителями десятичной
Как в скрипте проверить значение, возвращаемое родительским скриптом
Проблемы с Web PB
По поводу нажатия клавиш в билдере
Можно ли в PB 6.5 получить список имеющихся в программе окон и dw?
Хочется получить SQL-запрос, на котором базируется некое DW
О datawindow
Подскажите где можно прочитать про необходимый минимум shared dll для установки программы
Возможно ли написание на PB пpогpамы, котоpая бы поддеpживала многонитевость в pамках одной задачи?
Можно ли как-нибудь определить из приложения имя каталога, из которого его запустили (полное имя исполняемого модуля с путем)?
Открыть отчет
Индиректные переменные
Русская кодировка в Ягуаре
Проверка полей перед закрытием формы
Как получить значение Computed field
Как лучше расширять PFC
Стиль программирования
Где-нибyдь пеpечислены полностью константы для 'специальных' цветов фона контpолов в dw?
'Тайная закладка' в PowerBuilder 7 :)
Выделение цветом активной строки dw
dw и хранимые процедуры Oracle
Ссылки по PowerBuilder

Вопрос: Как пронумеровать группы? "Konstantin Goldobin" сообщил/сообщила в новостях следующее: GB> Торможу опять... Есть стандартное групповое DW, хочется в заголовок GB> группы положить вычисляемое поле чтобы оно могло показывать номер GB> группы в отчете. cumulativeSum( 1 for all distinct )
Вопрос: Как заставить powerbuilder интерпретировать динамически созданные скрипты? A> Hарод, где можно надыбать интерпретатор написанный на PowerBuilder, A> а еще было бы класно если же сам PB как то умел бы интерпретировать A> свои скрипты в из строки с исходником. Могу предложить для PB6 (на других версиях не проверял): Создаешь PBL с набором функций (можно объектов), включаешь его в проект, чтобы компилился как PBD. После компиляции этот PBD выкидываешь, пользуешь PBL. Разумеется, он должен включаться в список setlibrarylist(). В функции этого PBL, вызываемые из откомпилированного проекта, можно вносить изменения "на лету", без перекомпиляции проекта. Остальное зависит от полета фантазии ;) Пользователю PB устанавливать вовсе и не требуется, но включить некоторые DLL от PB все же придется, чтобы было чем редактировать интерпретируемую часть программы... С уважением, Andrey. E-mail: alpharegul@ukrpost.net ORCA API. В частности функция PBORCA_CompileEntryImport. Позволяет импортировать в PBL объект представленный в виде исходного текста. Не требует установленного PB поскольку нужен только один дополнительный DLL. Использует Callback-и поэтому потребуется "обвязка" на C++. Ну и еще пожалуй надо немного представлять себе как PB работает с PBL, pbd- чтобы изменения прошли нормально надо понимать как манипулировать Get/SetLibraryList чтобы не пытаться модифицировать файл, открытый PBVM. "Andrew Zorin"
Вопрос: Как определить размер объекта? Anatoly Moskovsky" сообщил/сообщила в новостях следующее: news:... DS> Это видимо общий размер. PBORCA_LibraryEntryInformation копай. Точно. DS> Hо их из Билдера вызывать нельзя - PBVM не реентерабельна... Может в 5 и так, но начиная с 6 - можно (кроме callbacks, их через вспомогательную DLL). global type s_entryinfo from structure character comments[256] long entrytime long objectsize long sourcesize end type function ulong PBORCA_SessionOpen () library "pborc60.dll" function long PBORCA_LibraryEntryInformation(& ulong hOrca, & readonly string as_lib, & readonly string as_entry, & long ai_type, & ref s_entryinfo info & ) library "pborc60.dll" ulong hOrca hOrca = PBORCA_SessionOpen() If hOrca = 0 Then MessageBox("","SessionOpen failed") halt End IF s_entryinfo ei long ret ret = PBORCA_LibraryEntryInformation(hOrca, "main.pbl", "app", 0, ei) If ret < 0 Then MessageBox("","LibraryEntryInformation failed: " + String(ret)) halt End IF MessageBox("", String(ei.ObjectSize) + "~r" + String(ei.SourceSize) + "~r") halt
Вопрос: Как узнать: существует ли объект в библиотеках не вызывая LibraryDirectory? VK> Как узнать: существует ли объект в библиотеках не вызывая LibraryDirectory? VK> Хотелось бы сотворить эдакий безопасный "CREATE USING" ClassDefinition cd String ls_class = "n_dynamic_class" cd = FindClassDefinition(ls_class ) If IsNull(cd) Then // raise error Else objref = Create Using ls_class End IF
Вопрос: Как скрестить PowerBuilder с Perl-ом? Вам сюда:
http://sqlbatch.com/t/dl.cgi?prod=util&id=perllib

Вопрос: Как сделать DDDW с параметром? Сначала нужно сделать dw с параметром для выпадающего списка. Затем, чтобы автоматически не вызывался retrieve без параметра для этого dddw, необходимо: Прописать событие pfc_populateDDDW: w_frame lw_frame lw_frame=gnv_app.of_getframe() SetPointer(HourGlass!) if (as_colname = 'yourcolumn') then if adwc_obj.RowCount() = 0 then adwc_obj.SetTransObject(SQLCA) adwc_obj.Retrieve( argumentForDDDW ) end if if adwc_obj.RowCount() = 0 then adwc_obj.insertrow(0) end if Return adwc_obj.RowCount() end if return NO_ACTION Далее в pfc_postopen добавляем вызов: dw.inv_base.of_populatedddw('yourcolumn')
Вопрос: Как найти строку с определенными значениями в полях DW? >Подскажите кто как pеализовует функцию поиска. Интеpесует поиск с >неполным значением (напpимеp aab*), на сколько pазбиpался функция Find >этого не умеет. 1. Если * в середине строки то только match: dw.Find("match(columnname, '^aaab.*ccccww$')",1, rowcount) 2. Если в конце(начале) строки (напpимеp aab*) то можно и так: ls_text = "firstchars" dw.Find("Left(columnname, "+ String(len(ls_text))+") = '" + ls_text+"'", 1, rowcount) Я думаю 2й способ быстрее. "Anatoly Moskovsky" 2-й ответ: Match DataWindow expression function: Match ( string, textpattern ) "Ilya Bricker"
Вопрос: Как переретривить одну строку? > табличный DW с чем-то там. По двойному клику или по пимпочке "Едит" > открывается другое окошко с текущей записью, но уже во всей > красе, так сказать, для редактирования/добавления новой записи. > Подскажите схематично реализацию этого всего. > И как сделать так, чтобы после редактирования второго обновлялось > первое - делать ретрив после обновления одной записи как-то не солидно ;) Syntax dwcontrol.ReselectRow ( row ) Description Accesses the database to retrieve values for all columns that can be updated and refreshes all timestamp columns in a row in a DataWindow control or DataStore. The values from the database are redisplayed in the row.
Вопрос: Как получить текстовое значение текущей строки в DDDW? dw.describe('evaluate("LookUpDisplay(data_column)",' + string(dw.GetRow()) + ')') "Nikulitsa Andrey"
Вопрос: Как переключаться между раскладками клавиатуры? В любом пайнтере, (Decare)-Global External Functions нужно объявить глобальные функции: FUNCTION long LoadKeyboardLayoutA ( ref string Lay, int Flags ) Library "USER32" FUNCTION long ActivateKeyboardLayout ( long Lay, int Flags ) Library "USER32" Затем создать функцию вроде этой (приведен файл экспорта): $PBExportHeader$f_ruslat.srf $PBExportComments$Функция переключения РУС/ЛАТ global type f_ruslat from function_object end type forward prototypes global subroutine f_ruslat (string as_language) end prototypes global subroutine f_ruslat (string as_language); String ls_Lay long ll_Lay, ll_OldLay if left(lower(as_language),3) = 'rus' then ls_Lay = '00000419' else ls_Lay = '00000409' end if ll_Lay = LoadKeyboardLayoutA ( ls_Lay, 0) If ll_Lay > 0 Then ll_OldLay = ActivateKeyboardLayout ( ll_Lay, 0) Else ll_OldLay = -1 end if end subroutine Теперь для переключения раскладок можете просто вызывать f_ruslat('rus') или f_ruslat('lat')
Вопрос: Как двигаться по DW по Enter? > Хочется сделать так же, как по TAB. Hа DW вешается event пользователя c Event ID: m_dwnprocessenter Скpипт для этого события: send(handle(this),256,9,long(0,0)) return 1 Andrey.Protopopov@p20.f2.n5022.z2.fidonet.org Еще ответ: Практически то же самое, только без использования send(...) и загадочных циферок :-) Почти такой же UserEvent EventName EventID ue_enter pbm_dwnprocessenter И скрипт по его обработке: int nCols nCols = Integer( this.Describe( "Datawindow.Column.Count" ) ) //кол-во колонок, надо еще вычесть невидимые :-) // в реальном скрипте стояло фиксир. число... int nCurrCol, i nCurrCol = this.getcolumn() // текущая колонка i = nCurrCol + 1 // идем не по TabOrder, а как сами пожелаем, здесь - на следующую DO WHILE ( this.Describe('#'+String(i, '0') +'.Visible') = '0' ) AND i <= nCols i++ LOOP // пропустили невидимые (здесь можно сбрасывать счетчик nCols) if i > nCols then // DW кончилось. Тогда переход на sle_1 sle_1.SetFocus() this.SetColumn( 'summa' ) this.ScrollToCol(1) else // вот сам переход по колонкам this.SetColumn( i ) this.ScrollToCol(i) end if return( 1 ) // чтобы Enter не отработал на переход вниз по столбцу Работало на PB 4.0, работает на PB 5.0 и 6.5, наверное, будет жить и на 7.0 Lesha@aitsoft.dol.ru
Вопрос: Как создавать ярлыки? (*.lnk) Вам сюда: http://www.pfcguide.com/extensions/ext_0014.asp
Вопрос: Как в группе строки пересчитать? last(getrow() for group 1) - first(getrow() for group 1) или sum(1 for group 1) Mark Lokshin <Mark.Lokshin@p147.f3.n5025.z2.fidonet.org>
Вопрос: Как в группе строки пронумеровать? getrow() - first(getrow() for group 1) + 1 Andrey. E-mail: dsm@kolosov.dn.ua Еще ответ: CumulativeSum(1 for group 1) Dmitri Grichine dgrichine@mail.ru
Вопрос: Как поставить pb без ASA? Наверное поможет следующее - в Registry в HKEY_CURRENT_USER\Software\SYBASE\Adaptive Server Anywhere\6.0 создаешь строковый параметр "Language" со значением "en". (такая поправка требуется для ASA 6.0.1, с последними бетами PB7 шла именно эта версия.) Roman V. Kabanov, rvk@rinet.ru
Вопрос: Как узнать, что приложение запущено из среды разработки? Handle( GetApplication() ) возвращает 0, если приложение запущено из-под среды PB.
Вопрос: Как получать значения полей dw, в том числе, вычислимых? 1) чеpез dot notation dw_sheet.Object.computedName[1] 2) чеpез describe('evaluate()') dw_sheet.describe('evaluate("computedName",1)') dw_sheet.describe('evaluate("expression",1)') и т.д. Если вложенные dw: Когда у тебя nested report в дpугом nested'е и т.д., то гоpаздо пpоще написать dw_sheet.Object.dw1.Object..., чем бpать getChild много pаз. Да и хоть я обычно и не получаю значения computed field'ов, но ситуация, когда в большом отчете getItem не pаботал, у меня была. Vlad.Ermolaev@p33.f16.n5025.z2.fidonet.org
Вопрос: Как отработать событие KeyPress на активном DWControle отмапить на pbm_dwnkey Hа пальцах (на всякий случ.) это выглядит так: - для DWControl создаешь свой userevent - при создании говоришь Paste: pbm_dwkey - в скрипте свежеиспеченного события проверяешь аргумент "key" (возможные варианты его значений - в хэлпе DownKey() ) - если желаешь прекратить обработку нажатия (т.е. - чтобы стандартное действие после твоего не выполнялось) - "Return 1" roma@pib.megastyle.com
Вопрос: Внешние функции L> Попробовал я написать внешнюю функцию (DLL) на VC++ 5 L> написал cpp L> __declspec(dllexport) char WriteA(void) 1) Она должна быть stdcall 2) Желательно extern "C" L> Откомпелил в CPAGE.DLL. L> В PB 6.0 прописал L> Function char WriteA()library "CPAGE.DLL" 2 1/2) ALIAS FOR "_WriteA@0" Еще ответ: Здесь карты путает C++. Попробуй компилить как C, или придется делать нечто такое: Function char WriteA() alias for "?WriteA@@YADXZ" library "CPAGE.DLL" С VC6.0 это работает Еще ответ: Опиши свои функции скажем так: #ifdef __cplusplus extern "C" { #endif void __stdcall(dllexport) far pascal yourfunc(void); .................................................... #ifdef __cplusplus } #endif Либо можешь в 5 vc еще использовать .def файл чтобы не юзать dllexport, например: LIBRARY YOURLIB DESCRIPTION 'YOURLIB DLL' ;STUB 'WINSTUB.EXE' ;EXETYPE WINDOWS CODE MOVEABLE PRELOAD DISCARDABLE DATA MOVEABLE PRELOAD SINGLE HEAPSIZE 4000 EXPORTS yourfunc @1 ; WEP PRIVATE И все дела. Ничего уродоваться не будет. А в dll желательно написать функцию загрузки- libmain для win16, либо dllmain для win32. Скажем например так: #ifdef WIN31 /*win16*/ int pascal LibMain (HANDLE hInstance, WORD wDataSeg, WORD wHeapSize, LPSTR lpCmdLine) { hInst = hInstance ; if (wHeapSize > 0) UnlockData (0); return 1; } BOOL far pascal WEP (int bSystemExit) { return (1); } #else /*win32*/ BOOL APIENTRY DllMain( HANDLE hModule, DWORD dwReason, LPVOID lpReserved ) { switch( dwReason ) { case DLL_PROCESS_ATTACH: break; case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; case DLL_PROCESS_DETACH: break; } return TRUE; } #endif
Вопрос: Использование стандартных функций C/C++ >>Пробовал ли кто-нибудь достучаться до API-шной функции "CopyMemory"? >>Дело в том, что она неэкспортируемая и обычным объявлением external >>function не получается :( >>Вообще, проблема в следующем: у меня есть массив Char c[8], где >>хранятся 8 байт, соответсвующие числу Duble. Как можно по этим байтам >>"сконструировать" значение для билдеровской переменной типа Double? >>Не хочется связываться с отделной DLL-кой ... FUNCTION long pbstg_huge_memcpy(ref double a , ref string b,int c) library "pbvm60.dll" В принципе тип параметров можешь менять. Это стандартная C функция. Этим же способом можно достучаться до любых C++ стандартных процедур. Vladimir Ritchkov
Вопрос: Глюки при импорте данных в dw, находящегося в querymode KG> У меня пpи вызове функций ImportString, ImportFile, ImportClipboard KG> для dw, находящегося в querymode, данные кладутся со втоpой стpоки KG> dw. Кто-нибудь боpолся? Победил? Методом научного тыка (проверялось на ImportString) выяснилось, что второй параметр этих функций используется в querymode как номер строки в DW перед которой будет идти вставка данных. Так что ImportString(ls_Data, 0) спасет... Konstantin Goldobin
Вопрос: Доступ ко вложенным отчетам в composite DW Пусть dw_composit_window -- название переменной композитного отчета, который содержит отчет, свойство name которого d_inside_window. В d_inside_window есть метка city_code_t, у которого нижеследющий текст меняет свойство text: DWObject InsideReport InsideReport = dw_composit_window.object.d_inside_window InsideReport.object.city_code_t.text = "!!!" Практически то же самое: DWObject InsideReport InsideReport = dw_composit_window.object.d_inside_window DWObject InsideInsideReport InsideInsideReport = InsideReport.object.d_inside_inside_window InsideInsideReport.object.city_code_t.text = "!!!" Или такой, хотя смотрится уродливо: dw_composit_window.object.d_inside_window.object.d_inside_inside_window.obje ct.city_code_t.text = "!!!" (На предыдущие ответы есть жалобы на ошибку во время выполнения) Есть такой ответ: У нас старый проект. (PB 5.0.4) Так в нем нормально работает следующий код --dw_report - композит --dw_header - отчет DataWindowChild dw_h dw_report.GetChild('dw_header', dw_h) dw_h.InsertRow(0) dw_h.SetItem( 1, 'address', 'Мой адрес не дом и не улица') dw_h.Modify("address.Height=80") Лично у меня на pb7.0.3 заработала такая комбинация: (смысл в том, что dwo присваивается не сам вложенный отчет, а один из его контролов) dwobject dwo dw_main.settransobject(SQLCA) dw_main.retrieve() dw_main.object.t_1.text="aaa" // item in main dw // ---- вот здесь вся фишка --------- dwo=dw_main.object.dw_1.object.user_t dwo.text="bbb" // item in child dw // ------------------------------ t_1 - текст в основном dw user_t - текст во вложенном dw
Вопрос: Хранимые процедуры Oracle как источних данных для DW >Создаю тестовую процедуру: >CREATE OR REPLACE PROCEDURE USER1.P_TEST >(A_DATE IN OUT DATE) AS >BEGIN > a_date := to_date('11.11.1911','DD.MM.YYYY'); >END; >Теперь пытаюсь создать dw, которое бы ретривило данные из процедуры: >DW Painter -> New -> >Выбираю Stored Procedure, Tabular >Выбираю из списка свою процедуру, жму ОК, появляется пустое DataWindow >(Untitled), с которым больше ничего нельзя сделать, кроме как закрыть. :( >Меню edit, objects, design, rows, кнопки SQL, Preview, Save, Вставка >объектов - заблокированы Процедура для dw обязательно должна возвращать какойнить result set :-) Короче с оракловыми процедурами и DW есть некоторый гимор. Тебе надо юзать тип ref cursor, т.е. указатель на курсор по которому ты и вернешь нужный тебе result set в DW. Первым параметром твоей процедуры будет переменная типа указатель на курсор. Ну а в процедуре открываешь этот ref курсор и все. Далее dw будет делать fetch и close через PB oci driver. Вот тебе батч для Sql Plus на твоем примере: Для оракла 7.2 (надо указывать возвращаемый курсором тип) create or replace package mycur as type rectype is record (dt date); type curtype is ref cursor return rectype; end mycur; / create or replace procedure mydwproc (dwresultset in out mycur.curtype) is begin open dwresultset for select to_date('11.11.1911','DD.MM.YYYY') from dual; end; / Ну и для оракла 7.3 и выше вообще просто (первый кста тоже сработает :-) ) create or replace package mycur as type curtype is ref cursor ; end mycur; / create or replace procedure mydwproc (dwresultset in out mycur.curtype) is begin open dwresultset for select to_date('11.11.1911','DD.MM.YYYY') from dual; end; / ЗЫ: datawindow прилепляешь ессно к mydwproc :-) WBR, Oleg Еще ответ: > g> А вот если использовать DYNAMIC SQL, то можно, сам пробовал > g> Эта возможность доступна с Oracle 8i > g> конструкция типа OPEN c FOR USING ... > g> sql_string - строка которую можно перед этим формировать > А поподpобнее ? Сампл есть какой нибудь ? К сожалению щас под рукой ничего реального нет, но вот: CREATE OR REPLACE PACKAGE DYNAMIC_CURSOR IS TYPE T_REF_CURSOR IS REF CURSOR; PROCEDURE get_cursor(out_cursor OUT T_REF_CURSOR); END; / CREATE OR REPLACE PACKAGE BODY DYNAMIC_CURSOR IS PROCEDURE get_cursor(out_cursor OUT T_REF_CURSOR) AS BEGIN OPEN out_cursor FOR 'SELECT 10 num FROM DUAL UNION SELECT 11 FROM DUAL'; END; END; / CREATE OR REPLACE PROCEDURE GET_CURSOR(out_cursor OUT DYNAMIC_CURSOR.T_REF_CURSOR) IS BEGIN OPEN out_cursor FOR 'SELECT 10 num FROM DUAL UNION SELECT 11 FROM DUAL'; END; / Делаешь новое DW указываешь последнюю процедуру потом экспортишь и заменяешь procedure="1 execute GET_CURSOR;0 " на procedure="1 execute DYNAMIC_CURSOR.GET_CURSOR ;0 " Импортишь обратно (все это проделано и проверено вовремя написания письма PB7.0.2 (8021) Oracle8i Personal Edition Release 8.1.5.0.0 - Production With the Java option PL/SQL Release 8.1.5.0.0 - Production) Я написал себе небольшую програмку которая строит DW по селекту, а потом подставляет туда пакедж Извините если я неверно понял вопрос и соответственно не то ответил. Dmitry Ibikus Еще ответ: N> Здравствуйте. N> Прошу откликнуться тех, кто решал задачу совмещения Билдера с Ораклом. N> Основной вопрос - заставить DataWindow видеть те stored procedure'ы, которые N> объявлены в package'ах, в качестве источника данных. На сайте Sybase я уже N> был, но там ничего подходящего не нашлось, поскольку придётся использовать N> CLOB'ы, а пятый Builder и понятия не имеет, что это такое. На смену версии N> Билдера начальство пойдёт только в крайнем случае - работающая часть системы N> уже есть на PB5, и вести разговор о переводе всех наработок на седьмой N> можно будет только в том случае, если не отыщется приемлемого способа N> провернуть это всё на пятом. Методика пока вроде одна: юзается тип ref cursor объявленный в отдельном package. В процедуру передаешь по ссылке курсор, который в ней _только открываешь, остальное сделает PB oci driver. Этот параметр будет проглочен DW, остальные будут как обычные аргументы. Очевидно что подобная процедура может быть в package, но для DW надо писать еще одну которая ее вызывает вне package c таким же набором аргументов. Для оракла 7.2 (надо указывать возвращаемый курсором тип) create or replace package mycur as type rectype is record (dt date); --для примера type curtype is ref cursor return rectype; end mycur; ----------------------------------------- Для оракла 7.3 и выше create or replace package mycur as type curtype is ref cursor ; end mycur; ----------------------------------------- Процедура для DW: create or replace procedure mydwproc (dwresultset in out mycur.curtype) is begin open dwresultset for select to_date('11.11.1911','DD.MM.YYYY') from dual; --например end; "NIISA" niisa@dialup.ptt.ru
Вопрос: Как избежать ошибок, связанных с разными разделителями десятичной части чисел (.,) > Стоит сервер 7.3.3. > Есть у меня в таблице поле number( 3,1 ). > В PB ( PowerBuilder 6 )- DW объекте есть это поле, установил ему маску > и формат: "#0.0". > Если в таблице сидит значение 0.5, то PB показывает в ячейке DW 5.0, > Если в таблице сидит значение 2.0, то PB показывает в ячейке DW 2.0, > Если в таблице сидит значение 1.5, то PB показывает в ячейке DW 15.0 > Попробуй выполнить в администраторе базы данных команду alter session set nls_numeric_characters = '.,'; И после этого перечитай DW. Иногда помогает. Александр
Вопрос: Как в скрипте проверить значение, возвращаемое родительским скриптом Вначале проверь не включил ли ты флажок Override ancestor script. Он включается на автомате, если ты создал скрипт события предка после скрипта наследника. В скрипте наследника: If AncestorReturnValue <> 1 Then // твои действия Else Return AncestorReturnValue End If
Вопрос: Проблемы с Web PB > У меня такая пpоблема: вpоде бы все настpоил, но пpи вызове > метода на клиенте (MS IE 4) получаю сообщение: > Error: PBWEBSetConfig: Could not find definition for Server Alias > '<server_alias>'. PBWEBRunRequest: PBWEBSetConfig has failed. > Hасколько я понимаю, пpивязка Server Alias к имени, собссно, сеpвеpа > пpиложений находится в файле pbweb.ini (его еще в pазных местах > доки обзывают pweb.ini, webpb.ini). > В этом инишнике у меня все пpописано как надо !!! Пример из моего PBWEB.INI : [idkdemo] application=pb_net_examples location=localhost driver=winsock [Cert-Rep] driver=winsock application=70000 location=175.210.135.63 > Может, Web.pb не находит этого инишника ??? Где он должен лежать ??? У меня живет в C:\WINNT, и вроде все находит. Погляди файл RUNEXAMP.HTM, он инсталлируется вместе с WebPB, в нем подробно расписаны все необходимые настройки. Roman V. Kabanov, rvk@i.am
Вопрос: По поводу нажатия клавиш в билдере > Вообщем так порешал я эту проблему > 1) У меня есть User Object типа DDLB - Так в нем маппируешь событие > pbm_cbneditchange на какое нибудь свое - например ue_char_key_press > и внутри него делаем что нибудь типа > ue_char_key_press ------------------- > int li_proccess=0,ls_idx = 0,li_start > string ls_txt = '' > > ls_txt = this.Text > li_start = len(this.Text) > ------------------------------------- > Тут еще можно поиграть с системными событиями pbm_enupdate,pbm_enchange > Одно из них приключается ДО диругое ПОСЛЕ того как нажмут клавишу > > 2)В dw легко определяется нажатая клавиша через pbm_dwnkey > А еще на каждую нажатую клавишу реагирует стандартное событие editchanged > > Best regards, > Leonid > mailto:leo@softincom.ru > > > Еще по этому поводу: > AN> А ты чего думал?;-)Я думаю чисто на Билдере трудно сделать еще лучше > Я думал, что как-нибудь можно. > AN> что-то. Можно попробовать через API Windows. > Hе, не пойдет - не понятно как ловить событие. Блин, тут начитаешься... Хук на клаву, API, событие other... В Билдере можно сделать все, что захочешь, если не извращаться без надобности. В свое время служба поиска при наборе мною была написана за двое суток без малейших раздумий. Case - так case, берем DynaText, из него копируем список keycode, переводим на русский (украинский по вкусу), добавляем немного powerscript-а (естественно, в ultraedit-е), все, готово, час работы. Ему (PB) не уравнения же решать на скорость, зачем же что-то изобретать? Да, будешь писать службу, посмори на n_cst_dwsrv_dropdownsearch из PFC. Это не то, что тебе нужно, но проще всего отталкиваться от нее. В общих чертах, писать ничего не придется, только заменить DDDW на edit и убрать все лишнее :-) [skipped] > я хочу сделать компонент, на основе DataWindow, в котоpом pеализовывалась бы > эта возможность, но уже паpу дней не могу найти способа как это сделать не > чеpез известное место. Очень похоже, что с этого места ты и начал. Зачем тебе здесь ASCII, если все равно приводить к string, т.к. сравнивать надо с содержимым экранного буфера (отображением) поля? Лови Сase, если нужен именно ASCII, а не string, пройдись каким-нибудь редактором с хорошим replace или ручками. А вообще, моя служба поиска при наборе работает, отлично, могу поделиться но сюда запостить не могу, т.к.сейчас нет прямого доступа в ФИДО, а в ней > 35K текста (попрошу не пугаться, из них половина - комментарии, копирайты и terms of use), в zip-е 5K, но добрейший сервер, через который я хожу, не понимает attachment-ов. Так что спроси кого-нибудь, у кого есть e-mail-ьный адрес, сюда переслать zip, или, если модератор разрешит, кину текст... ////////////////////////////////////////////////////////////////////////////// // // Function: n_cst_string::of_string // // Arguments: // // Returns: string // // Description: // // Note: // ////////////////////////////////////////////////////////////////////////////// // // Modifications: // // Date Author Comments //---------------------------------------------------------------------------- // 16.03.00 V.Kolodiazhnyi Created ////////////////////////////////////////////////////////////////////////////// String ls_null If IsNull(key) Then SetNull (ls_null) Return ls_null End If //Russian Character set if Layout = LAYOUT_RUSSIAN then if KeyFlags = 0 then Choose Case key Case keya!; Return 'ф' Case keyb!; Return 'и' Case keyc!; Return 'с' Case keyd!; Return 'в' Case keye!; Return 'у' Case keyf!; Return 'а' Case keyg!; Return 'п' Case keyh!; Return 'р' Case keyi!; Return 'ш' Case keyj!; Return 'о' Case keyk!; Return 'л' Case keyl!; Return 'д' Case keym!; Return 'ь' Case keyn!; Return 'т' Case keyo!; Return 'щ' Case keyp!; Return 'з' Case keyq!; Return 'й' Case keyr!; Return 'к' Case keys!; Return 'ы' Case keyt!; Return 'е' Case keyu!; Return 'г' Case keyv!; Return 'м' Case keyw!; Return 'ц' Case keyx!; Return 'ч' Case keyy!; Return 'н' Case keyz!; Return 'я' Case KeyQuote!; Return 'э' Case KeyComma!; Return 'б' Case KeyPeriod!; Return 'ю' Case KeySlash!; Return '.' Case KeyBackQuote!; Return 'ё' Case KeyLeftBracket!; Return 'х' Case KeyRightBracket!; Return 'ъ' Case KeySemiColon!; Return 'ж' End Choose else Choose Case key Case keya!; Return 'Ф' Case keyb!; Return 'И' Case keyc!; Return 'С' Case keyd!; Return 'В' Case keye!; Return 'У' Case keyf!; Return 'А' Case keyg!; Return 'П' Case keyh!; Return 'Р' Case keyi!; Return 'Ш' Case keyj!; Return 'О' Case keyk!; Return 'Л' Case keyl!; Return 'Д' Case keym!; Return 'Ь' Case keyn!; Return 'Т' Case keyo!; Return 'Щ' Case keyp!; Return 'З' Case keyq!; Return 'Й' Case keyr!; Return 'К' Case keys!; Return 'Ы' Case keyt!; Return 'Е' Case keyu!; Return 'Г' Case keyv!; Return 'М' Case keyw!; Return 'Ц' Case keyx!; Return 'Ч' Case keyy!; Return 'Н' Case keyz!; Return 'Я' Case KeyQuote!; Return 'Э' Case KeyComma!; Return 'Б' Case KeyPeriod!; Return 'Ю' Case KeySlash!; Return ',' Case KeyBackQuote!; Return 'Ё' Case KeyLeftBracket!; Return 'Х' Case KeyRightBracket!; Return 'Ъ' Case KeySemiColon!; Return 'Ж' //characters that depends from language only when shift key is pressed Case key0!; Return ')' Case key1!; Return '!; ' Case key2!; Return '"' Case key3!; Return '¦' Case key4!; Return ';' Case key5!; Return '%' Case key6!; Return ':' Case key7!; Return '?' Case key8!; Return '*' Case key9!; Return '(' End Choose end if else if KeyFlags = 0 then Choose Case key Case keya!; Return 'a' Case keyb!; Return 'b' Case keyc!; Return 'c' Case keyd!; Return 'd' Case keye!; Return 'e' Case keyf!; Return 'f' Case keyg!; Return 'g' Case keyh!; Return 'h' Case keyi!; Return 'i' Case keyj!; Return 'j' Case keyk!; Return 'k' Case keyl!; Return 'l' Case keym!; Return 'm' Case keyn!; Return 'n' Case keyo!; Return 'o' Case keyp!; Return 'p' Case keyq!; Return 'q' Case keyr!; Return 'r' Case keys!; Return 's' Case keyt!; Return 't' Case keyu!; Return 'u' Case keyv!; Return 'v' Case keyw!; Return 'w' Case keyx!; Return 'x' Case keyy!; Return 'y' Case keyz!; Return 'z' Case KeyQuote!; Return "'" Case KeyComma!; Return ',' Case KeyPeriod!; Return '.' Case KeySlash!; Return '/' Case KeyBackQuote!; Return '`' Case KeyLeftBracket!; Return '[' Case KeyRightBracket!; Return ']' Case KeySemiColon!; Return ';' end choose else Choose Case key Case keya!; Return 'A' Case keyb!; Return 'B' Case keyc!; Return 'C' Case keyd!; Return 'D' Case keye!; Return 'E' Case keyf!; Return 'F' Case keyg!; Return 'G' Case keyh!; Return 'H' Case keyi!; Return 'I' Case keyj!; Return 'J' Case keyk!; Return 'K' Case keyl!; Return 'L' Case keym!; Return 'M' Case keyn!; Return 'N' Case keyo!; Return 'O' Case keyp!; Return 'P' Case keyq!; Return 'Q' Case keyr!; Return 'R' Case keys!; Return 'S' Case keyt!; Return 'T' Case keyu!; Return 'U' Case keyv!; Return 'V' Case keyw!; Return 'W' Case keyx!; Return 'X' Case keyy!; Return 'Y' Case keyz!; Return 'Z' Case KeyQuote!; Return '"' Case KeyComma!; Return '<' Case KeyPeriod!; Return '>' Case KeySlash!; Return '?' Case KeyBackQuote!; Return '~~' Case KeyLeftBracket!; Return '{' Case KeyRightBracket!; Return '}' Case KeySemiColon!; Return ':' //characters that depends from language only when shift key is pressed Case key0!; Return ')' Case key1!; Return '!; ' Case key2!; Return '@' Case key3!; Return '#' Case key4!; Return '$' Case key5!; Return '%' Case key6!; Return '^' Case key7!; Return '&' Case key8!; Return '*' Case key9!; Return '(' end choose end if end if if KeyFlags = 0 then Choose Case key //characters that depends from language only when shift key is pressed Case key0!; Return '0' Case key1!; Return '1' Case key2!; Return '2' Case key3!; Return '3' Case key4!; Return '4' Case key5!; Return '5' Case key6!; Return '6' Case key7!; Return '7' Case key8!; Return '8' Case key9!; Return '9' //characters that don't depends from language Case KeyEqual!; Return '=' Case KeyDash!; Return '-' Case KeyBackSlash!; Return '\' End Choose else Choose Case key //characters that don't depends from language Case KeyEqual!; Return '+' Case KeyDash!; Return '_' Case KeyBackSlash!; Return '|' End Choose end if //characters that don't depends neither from language nor from keyflags Choose Case key Case KeySpaceBar!; Return ' ' Case KeyNumpad0!; Return '0' Case KeyNumpad1!; Return '1' Case KeyNumpad2!; Return '2' Case KeyNumpad3!; Return '3' Case KeyNumpad4!; Return '4' Case KeyNumpad5!; Return '5' Case KeyNumpad6!; Return '6' Case KeyNumpad7!; Return '7' Case KeyNumpad8!; Return '8' Case KeyNumpad9!; Return '9' Case KeyMultiply!; Return '*' Case KeyAdd!; Return '+' Case KeySubtract!; Return '-' Case KeyDecimal!; Return '.' Case KeyDivide!; Return '/' end choose //Invalid parameter Return ''
Вопрос: Можно ли в PB 6.5 получить список имеющихся в программе окон и dw? LibraryDirectory ( libraryname, objecttype ) далее по хелпу
Вопрос: Хочется получить SQL-запрос, на котором базируется некое DW Самый простой способ - через datastore Пример: Datastore lds String ls_sql lds = Create DataStore lds.DataObject = "d_datawindow" lds.SetTransObject(sqlca) // если запрос руками был сделан то этого можно не делать ls_sql = lds.GetSqlSelect() Destroy lds
Вопрос: О datawindow RG> Моя проблемка начинается подобным образом - я также для dw меняю его RG> .dataobject, но, кроме этого, у меня есть пара таких DW, которые при RG> запуске окна имеют .Visible=False, в скрипте открытия решается какой тип RG> данных и вид DW надо применять и объектной переменной Datawindow RG> присваивается имя объекта нужного dw-control IMHO это не лучший способ - накладывать друг на друга DW, и переключать при помощи Hide/Show. Более рационально каждое из DW вставить в UO, и когда окно решит, какое из DW применить, оно должно выполнить openUserObject(). А в конструкторе каждого UO, прописываешь каким образом инициализировать DW. RG> и при необход.меняется RG> .dataobject. Лучше менять не dataobject, а грузить форму из PBL библиотеки: dw.Create(LibraryExport(libName, formName, ExportDataWindow!)) Этим ты не только высвобождаешь место в EXEшнике, но и изолируешь себя от всяческих неожиданностей, ведь ceate создает dw практически заново. Кроме того у тебя появляется возможность корректировать и менять формы DW непостедственно во время работы программы. RG> Так вот, все эти DW на Externale и при открытии окна в них RG> инсертится RG> запись, которой я через .object.data[,] присваю дефоултовое значение, RG> например для даты - Today(). В данном случае лучше применить свойство initial или еще лучше ввести today в initial value в момент редактирования dw в dw паинтере. RG> Hо! в начале редактирования значение этой строки вместо RG> "26.02.1999" - RG> "00.00.0000". Если значение не изменять, а сдвинуться на след.строку, то RG> станет видимым истинной значение. Это как-то раздражает, начинаешь RG> непроизвольно ввожить дату, хотя она там есть... Такое я встречал в зашареных окнах, спасался передергиванием строк через setrow(0); setrow(lastrow) :( А вообще, IMHO, External с точки зрения дизайна очень не удобны. Я в последнее время вообще отказался от них и не жалею. Если нужно "абстрактное окно" без привязки к конкретной таблице, создаю SQL Select с запросом типа: select '' as name1, cast(null as date) as name 2, cast(null as double) as name 3, ............................. from dummy Плоучаешь тот же External, но: 1. Hормально работает preview 2. Без проблем меняются имена и типы полей. 3. При большом количестве полей очень удобно работать в data source, а при необходимости групповой замены в полях текст из data source можно скопировать в любой текстовый редактор и там обработав, вставить обратно.
Вопрос: Подскажите где можно прочитать про необходимый минимум shared dll для установки программы Я нашел описание ВСЕХ DLL только для 5-го PowerBuilder на старой странице Крега Вагнера http://www.thehindu.co.in/INTRANET/software/powerbuilder/powerbuilder_faq.sHTML.htm номер ответа [2.1] Его обновленная страница находится здесь: http://www.mindspring.com/~craig_wagner/powerbuilder_faq.html но теперь ответ [2.1] значительно обрезан. В седьмом PB нужно еще добавить DLL для Jaguar, даже если она не нужна. По-моему, ее имя начинается на lib.... Еще ответ: Необходимые DLLки: 1. PBVM70.DLL - PowerBuilder Virtual Machine - самая главная, без нее никуда. 2. PBDWE70.DLL - DataWindow Engine. Если DW не используется, можно обойтись без нее. Но с другой стороны, какая же PB-прилада обходится без Datawindow ? ? ? 3. PBSYC70.DLL - Native-driver для работы с БД (в данном случае для Sybase ASE ). Кто использует другие базы - тому соотвественно другие библиотеки. PBO8470.DLL - Оракл, PBIN970.DLL - Информикс, далее смотри в документации. 4. LIBJCC.DLL - поддержка Jaguar, нововведение седьмого билдера. Даже если программа не имеет никакого отношения к Ягуару, библиотека все равно нужна, такая вот хитрость.... Это все было на тему PB7. Для PB6 справедливо следующее: 1. PBVM60.DLL 2. PBDWE60.DLL 3. PBSYC60.DLL (or PBO7360.DLL, or PBIN760.DLL, or ...) Roman V. Kabanov, rvk@i.am
Вопрос: Возможно ли написание на PB пpогpамы, котоpая бы поддеpживала многонитевость в pамках одной задачи? на PB 5 - нельзя. на PB 6.x - можно, используя Shared Objects. <Отрывок из примера> /* create runtime environments for thread */ SharedObjectRegister('nv_test','object1') /* get poiner to the object */ SharedObjectGet('object1',inv_Test1) /* start thread */ inv_Test1.POST of_Start() Andrey Zorin St.Petersburg, Russia ICQ UIN 2276239 mailto:azorin@email.com Welcome to #powerbuilder IRC channel (Undernet)
Вопрос: Можно ли как-нибудь определить из приложения имя каталога, из которого его запустили (полное имя исполняемого модуля с путем)? Имя каталога определяется так: string ls_AppPath string ls_FullPath, ls_RevPath int li_Pos, li_Pos2 // получение полного имени ClassDefinition lcd n_dummy_obj u If IsNull(u) Then u = Create n_dummy_obj // если не autoinstantiated lcd = u.ClassDefinition ls_Fullpath = lcd.LibraryName // выделение имени каталога ls_RevPath = Reverse(ls_FullPath) li_pos = Pos(ls_RevPath, "\") li_pos2 = Pos(ls_RevPath, "/") If li_pos2 > 0 and li_pos > li_pos2 Then li_Pos = li_Pos2 End If If li_pos > 0 Then ls_AppPath = Left(ls_FullPath, Len(ls_FullPath) - li_pos) Else ls_AppPath = "." End IF return ls_AppPath Вместо "n_dummy_obj" можно подставить любой(почти) класс, который находится в исполняемом модуле. Для того чтобы при компиляции объект поместился в EXE надо в проекте снять галку в поле "DLL/PBD" напротив библиотеки с этим объектом. Хотя если все библиотеки находятся в одном каталоге, можно не заботиться об этом. Есть еще и другой вариант (win32): Описываешь external function: function long GetModuleFileNameA (long module, ref string path, long length) library "kernel32.dll" А потом вызываешь ее: ls_Fullpath = Space (255) li_Ret = GetModuleFileNameA (Handle(GetApplication()), ls_FullPath, 255) Здесь мы имеем полный путь к EXE. Далее разбор пути как показано выше. Хотя мне больше нравится первый вариант.
Вопрос: Открыть отчет AK> А как собственно осуществить сабж из приложения. AK> Что-то не ншел в мануале. Ежели Отчет имеется в виду datawindow для печати так откpываешь его как обычный и ставишь свойство <dataobject>.object.DataWindow.Print.Preview = "Yes" (так кажется ) А ежели он лежит в отдельной PBLке котоpая к пpоекту не пpилинкована, тогда так <StringVar> = LibraryExport(<Library>,"report name",ExportDataWindow!) <dataobject>.Create(<StringVar>,<ErrorVar>) ^^^^^^^^^ сюда он ошибку пишет
Вопрос: Индиректные переменные >> Описано у Галлагера на стр. 157 >>Переменную можно объявить, чтобы чтение и запись выполнялись через функции: >>Indirect <тип> <имя> {<процедура_записи>(*value),<функция_чтения>()} >>после <имя> = Message.Powerobject вызовется <процедура_записи> >SS>Если можно, поподробнее. Ни в хелпе ни в онлайнбуке ничего по этому поводу >SS>нет, есть только зарезервированное слово, Эксперименты тоже ничего не дали. >SS>Пробовал на 6.5. Может это фича 7-ки? Была еще в 4-ке. Только плохо работала. Вот пример условно: Intstance : long tn string s Indirect string Z {gt(*value),pt()} // Можно только в Instance!!! procedure gt(int a) tn=a string function pt() <Здесь , допустим , поиск фамилии по табельному tn и занесение в s> return s Описание : Использование: Z=1101 // Табельный sle_1.text="ФИО: "+Z // Фамилия Заметь, что переменной Z вообще не существует. Кстати , все элементы структур - Indirect.
Вопрос: Русская кодировка в Ягуаре > Hе поможет ли кто со следующей проблемой. > Использую PowerBuilder-овский COM-объект для генерации HTML > путем вызова его из ASP-страниц. Так вот любой элемент DW-объекта > с русским текстом в броузере (любом и с любыми шрифтами) отображается > неправильно. В приложении этот же DW работает нормально. > Вставил на выходе вызываемого метода генерации HTML сброс текста > в файл, просматриваю - все нормально. Если в теле самой ASP-страницы > есть русские символы, или что-то типа > document.Write("Привет") > то все выводится нормально. > Самое интересное, если вместо COM вставляю свой объект в Jaguar, > то кодировка тоже меняется, но по-другому. > В чем может быть дело,и как с этим бороться? По поводу ягуара - он принципиально не понимает русский - чтобы он понял надо в нескольких настроечных файлах прописать вручную использование русского языка и добавить русские charsets и locales. И естествонно потом перегрузить. И ещё после каждого редактирования компонента в ягуаре восстанавливать русскую кодовую страницу в настроечном файле соответствующего компонента.
Вопрос: Проверка полей перед закрытием формы >в событии ItemChange, и хотелось бы просто в конце просто вызывать это событие >для каждого поля формы, но вот только вызов этого события требует в параметрах >DWObject. И мне не удалось найти средство для получения его по ходу выполнения >программы. Пример из работающей программы: Фунцкия окна, которой передается as_objname и dwo - про ссылке, т.е.тот самый dwo что и требуется. (Данная фунцкия использовалось, когда нужно было инициировать события itemchanged после того как была нажата кнопка в dw и выполнен некоторый скрипт, который в свою очередь правил некоторые поля ради которых и должно быть отработано событие itemchanged.) Может быть получилось не так изящно как хотелось бы ;-)) /* of_GetDWObject(as_objname, dwo) Получение DWObject по имени DW-объекта Поддерживается до 59 объектов в DW (А зачем больше?) */ String ls_ret Int li_index, li_ret = 1 ls_ret = this.Describe(as_objname + '.ID') if ls_ret = '!' or ls_ret = '?' then li_ret = -1 else choose case Long(ls_ret) case 0 dwo = this.Object.#0 case 1 dwo = this.Object.#1 ... ... & etc. ... case 58 dwo = this.Object.#58 case 59 dwo = this.Object.#59 case else li_ret = -1 end choose end if return li_ret
Вопрос: Как получить значение Computed field GN> Есть какой-то субж, скажем "compute_5". GN> В нем чего-то там подсчитывается, скажем некая сумма по некоему условию. GN> Как в скрипте получить значение вычисленного выражения в даном компутед GN> фиелде ? Hе выражение, а именно готовую цифру. Hапример, [start script for example] decimal ld_some_var ld_some_var = dw_1.object.compute_5[1] MessageBox('',String(ld_some_var)) [end] В мессадже боксе будет твоя сумма. А вообще, читай хелп там про это написано. Этот скрипт работает, если вычислимое поле находится в полях summary and footer DW, если выч поле находится в detail, то там немного по другому - я сейчас не помню...
Вопрос: Как лучше расширять PFC PVV> А каким путем добавлял слой, ручками или через соответствующую утилиту PFC PVV> Library Extender? PVV> Последнее мне кажется предпочтительней, поскольку человеку свойственно PVV> ошибаться. Потом далеко не все объекты в наследовании имеют иерархию pfc_* > pfe.* Есть, например, конструкции pfc_* => pfe.* => pfc_* => pfe.* >Слой добавлял pучками, т.к не в куpсе пpо утилиту. Где она беpется Я ставил 6.0 потом патчил до 6.5 и вроде эта утилита появилась (хотя может и до патча была непомню, как то не было у меня таких проблем) А если 5 Билдер, то в "полном" последнем патче точно есть (этого я уже точно не помню - давно было). Под полным я имею ввиду, что брал патч не из инета, а у Московского Sybase, там много всего, в том числе и translation toolkit (для локализации приложения)...вобщем там целая помойка, а не несколько файлов как в инете. > и какие дает пpеимушества? Как уже писал - вероятность ошибки => 0 (если конечно программа безупречна) И что не маловажно - делается это за считанные минуты. Время - деньги, если есть деньги не трать время ;-) > Иеpаpхия наследования в моем случае, думаю, не имеет большого значения, >т.к. все объекты пpиложения наследуются из pfe_, а подменять пытаюсь все слои >библиотек после фулл pебилд. А вот и имеет и причем огромное! Короче, воспользуйся утилитой - она тебе многое объяснит. >> >> Объясните кто - нибудь почему не удается создавать новые функции, что >> значительно сковывает возможности совеpшенствования PFC и поpтит стиль ______________________ Pavel V. Vinogradov pavel@custody.ru
Вопрос: Стиль программирования Делаеш скажем так БАЗОВУЮ_МАШИУ_УИВЕРСАЛЬОГО_ПОВЕДЕИЯ (БМУП). Твоя задача - опpеделить поведение этой машины в контексте конкpетного объектного окpужения. Для выполнения этой задачи фоpмулиpуеш язык позволяющий на уpовне иф-логики сказать БМУП какие компоненты откуда взять и какие пеpеменные пpименить. апpимеp: Пpи pаботе со спpавочником ты можешь: 1) выполнять поиск (выполнение выбоpки pяда стpок в соответствие с к-л кpитеpием) 2) Выполнить добавление или удаление стpок в (из) выбоpки. 3) Выполнять модификацию объектов соответствующих каждой стpоке выбоpки Создаем БМУП для выполнения этих задач - окно с DW-контpолом и кнопками [Искать] [Добавить] [Удалить] [Модифициpовать] БМУП полностью унивеpсальна и абстpактна в отношении DW-обжекта (за исключением атpибутов поиска, но о них позже) Кнопки [Добавить] [Удалить] вызывают конкpетные интеpфейсы DW-controla Кнопка [Модифициpовать] вызывает окно pедактиpования объекта, соответствующего текущей стpоке выбоpки. Окно pедактиpования фоpмулиpувется как отдельная БМУП Кнопка [Поиск] выполняет унивеpсальное действие: retrieve для dw - control в соответствии с кpитеpиями поиска Остается извне описать: - имя dw-object котоpый будеp pазмещен на окне - список кpитеpиев поиска (способ их получения из текущего окна или окон окpужения) - ссылку на описание окна pедактоpа объекта. Все!!! Остается заpегистpиpовать библиотеки ч-з setlibrarylist и вызвать к жизни БМУП окна поиска пpименительно к созданному описанию. Я сделал подобную библиотечку. Использую ее пpомышленно. Эффект поpазительный. Кpупные пpоекты содеpжат не более 5-6 окон создаваемых в PB (не считая объектов базовых абстpакций). В билдеpе создаются пpактически одни datawindow object. Если интеpесно - могу кинуть описание. Stas.V.Lipchansky@p14.f177.n465.z2.fidonet.org
Вопрос: Где-нибyдь пеpечислены полностью константы для "специальных" цветов фона контpолов в dw? NS> Hе знаю, где они есть, самой интересно. NS> Я взяла из этой эхи: NS> ButtonFace: 79741120 NS> Text: 33554432 NS> Background: 1090519039 NS> AppWorkSpace: 276856960 Остальные основные цвета можно найти в постовляемом вместе с PB Watcom C. H\graph.h Еще ответ: >I determined these windows colours by setting objects with the colour, >exporting and then checking the values (they do work). > >string cs_WinBack = "1090519039" >string cs_ButtonFace = "79741120" >string cs_WinText = "33554432" >string cs_AppWkSpc = "276856960" I've been experimenting with this, starting with the suggestions from Daryl Anderson. I've found that the colors are represented in a LONG (4 byte word). The bottom three bytes are the RGB value. With a "normal" color, that's all that's used. For a System color, the top byte contains the code denoting the system color.I suspect, but can't prove, that these codes are different on different platforms. For Windows, the codes that I've found are (in hex notation): Button Face: 04 Window Text: 02 Window Background: 40 Application Work Space: 10 If we could use hex constants in PowerScript, it would be simple to specify the value of the "long" value to get a system color. Since we can't, we have to code the decimal value instead: ButtonFace = 0x04000000 = 67108864 WindowText = 0x02000000 = 33554432 WindowBackground = 0x40000000 = 1073741824 Application Work Space = 0x10000000 = 268435456 The reason that the different values you supply will also work is because they set the top byte of the word to the correct code. WHen that happens the bottom three bytes are ignored. (Probably, PB sees the code in the top byte, gets the proper color from the system, and stores that in the bottom three bytes). -- Tim Slattery Slattery_T@bls.gov
Вопрос: 'Тайная закладка' в PowerBuilder 7 :) Чтобы увидеть ее, делаем следующее: 1. Запускаем PB7 2. Вызываем Help/About 3. На клавиатуре набираем слово powersoft (хорошее слово...) 4. Нам покажут довольно юморную надпись ;-)))), и после нее - список всех тех людей, которые участвовали в создании PB. 'Фича' сия проверена на 7.0.2 Build 8046. Roman V. Kabanov, rvk@i.am
Вопрос: Выделение цветом активной строки dw VB> Я использую для указания активной строки следующий компьютедфилд VB> колор: if(getrow()=currentrow(),RGB(255,255,255),RGB(0,0,0)) VB> бакгроунд.колор:if(getrow()=currentrow(),RGB(0,0,128),2^26) с похожим скриптом я когда-то возился с проблемой различного кол-ва цветов видяхи на машине клиента - иногда текст становился прямо-таки нечитабельным.. И во всех своих DW активную строку начал выделять не цветом, а бордюром: border="0~tif(currentRow()=getrow(), 2, 0 )" (это из .srd ;) а цвета теперь играют лишь роль смыслового выделения групп колонок (и всегда пробую данное DW посмотреть с разной установкой цветов-разрешения)
Вопрос: dw и хранимые процедуры Oracle Короче с оракловыми процедурами и DW есть некоторый гимор. Тебе надо юзать тип ref cursor, т.е. указатель на курсор по которому ты и вернешь нужный тебе result set в DW. Первым параметром твоей процедуры будет переменная типа указатель на курсор. Ну а в процедуре открываешь этот ref курсор и все. Далее dw будет делать fetch и close через PB oci driver. Для оракла 7.2 (надо указывать возвращаемый курсором тип) create or replace package mycur as type rectype is record (dt date); type curtype is ref cursor return rectype; end mycur; / create or replace procedure mydwproc (dwresultset in out mycur.curtype) is begin open dwresultset for select to_date('11.11.1911','DD.MM.YYYY') from dual; end; / Ну и для оракла 7.3 и выше вообще просто (первый кста тоже сработает :-) ) create or replace package mycur as type curtype is ref cursor ; end mycur; / create or replace procedure mydwproc (dwresultset in out mycur.curtype) is begin open dwresultset for select to_date('11.11.1911','DD.MM.YYYY') from dual; end; / ЗЫ: datawindow прилепляешь ессно к mydwproc :-)
Hosted by uCoz