WinApi

Программы на Clarion, шаблоны, библиотеки и пр.

Модератор: Дед Пахом

Правила форума
При написании вопроса или обсуждении проблемы, не забывайте указывать версию Clarion который Вы используете.
А так же пользуйтесь спец. тегами при вставке исходников!!!
Ответить
RozAlex
Посетитель
Сообщения: 34
Зарегистрирован: 06 Июль 2005, 16:39
Откуда: Moscow
Контактная информация:

Сообщение RozAlex »

Добрый день всем!

С55, авс,шаблон РТФ В.Дегтяренко+шаблон Solace для изменения разрешения экрана
Есть моя глобальная переменная glo:UseId, которая получает какое-то значение, а вот после следующей строки, которую генерирует шаблон:
EnumDisplaySettings(0,DmMode,GLO:DM)

это значение изменяется ! что может быть?

Код: Выделить всё

GLO:DM  Group(DevMode),pre(GDM)
        END
DEVMODE       GROUP,TYPE
DeviceName    BYTE,DIM(32)
SpecVersion   short 
DriverVersion short 
Size          short 
DriverExtra   short Fields        ulong
Orientation   short
PaperSize     short
PaperLength   short
PaperWidth    short
Scale         short
Copies        short
DefaultSource short
PrintQuality  short
Color         short
Duplex        short
YResolution   short
TTOption      short
Collate       short
FormName      BYTE,DIM(32)
LogPixels     short
BitsPerPel    long
PelsWidth     long
PelsHeight    long
DisplayFlags  short
            END
Заранее благодарна
с Уважением Ольга

Написал: RozAlex(1)
Гость

Сообщение Гость »

Первое, что приходит в голову - в структуру GLO:DM пишеться больше данных, чем ее размер.
В результате этого перезаписываются и переменные, которые непосредственно идут после этой структуры.

Кстати 1: каким размером инициализируется поле DEVMODE.Size?
Кстати 2: поле DisplayFlags имеет тип LONG.
Кстати 3: описание структуры DEVMODE - неполное - там еще есть несколько полей.

=============================
С уважением, Олег А. Руденко.
Oleg_Rudenko@mail.ru
Oleg_Rudenko@mail333.com
Библиотека DynaLib
http://dynalib.narod.ru

вот кусок из проги в том порядке как идет определение

Код: Выделить всё

program
...
DEVMODE       GROUP,TYPE  ------------> шаблонная
DeviceName    BYTE,DIM(32)
SpecVersion   short 
DriverVersion short 
Size          short 
DriverExtra   short 
Fields        ulong
Orientation   short
PaperSize     short
PaperLength   short
PaperWidth    short
Scale         short
Copies        short
DefaultSource short
PrintQuality  short
Color         short
Duplex        short
YResolution   short
TTOption      short
Collate       short
FormName      BYTE,DIM(32)
LogPixels     short
BitsPerPel    long
PelsWidth     long
PelsHeight    long
DisplayFlags  short
            END

   MAP
   ....

GLO:UseId          BYTE    ----------> моя переменная
SOLDisplayQ        QUEUE,PRE(GDQ)  ---------- шаблонная
Desc                 STRING(30)
Height               LONG
Width                LONG
BitsPerPel           BYTE
DMode                LONG
OK                   BYTE
                   END
SilentRunning        BYTE(0)   
GLO:DM  Group(DevMode),pre(GDM)
        END
DisplayFrequency            long
Glo:NeedToResetResolution    BYTE
Glo:OrigDisplayWidth         LONG
Glo:OrigDisplayHeight        LONG
Glo:OrigDisplayBPP           LONG
        

DisplayQ    Queue,pre(DQ)
Desc          String(30)
DM            Group(DevMode)
              end
ok            byte
            END
определение этой структуры GLO:DM идет ПОСЛЕ моей переменной
поиск инициализации DEVMODE.Size ничего не дал, видимо... :(
это работа шаблона

Hello Олег,

эксперимент показал, что вставка "буферной переменной" после моей такого же размера (byte) предохраняет ее от изменений:( теперь меняется уже буферная, где-то видимо действительно наезжают данные этой структуры на мои...знать бы что еще может изменяться по ходу дела в моих переменных...где-то ошибка в определении этой структуры?

--
Best regards,
olga

Если умеешь пользоваться Клашиным отладчиком, то можешь посмотреть порядок расположения глобальных данных в реальной памяти - компилятор НЕ ВСЕГДА располагает их в том порядке, как они обьявлены в коде - особенно касается структурных переменных типа GROUP/CLASS/QUEUE/FILE/VIEW.
Или можешь поступить еще проще - после старта программы выведи с помощью MESSAGE адреса и РЕАЛЬНЫЕ размеры всех своих глобальных переменных - сразу и определишь, кто конкретно стоит ПЕРЕД и ПОСЛЕ "проблемной" переменной.

Только после этого можно будет сказать что-то более конкретное.

Кстати, я очевидно пропустил, но - какая версия Клариона?
Дело в том, что в C61 расположение переменных и их инициализация несколько другие чем в предыдущих версиях - таким образом SV пытаются минимизировать время инициализации блока трейдовых переменных при открытии нового потока.

=============================
С уважением, Олег А. Руденко

версия клары 5.5 с 8 -мым патчем
Олег, спасибо за помощь!
И еще один нюанс вылез - не знаю связан ли с этим или нет...
Этот шаблон при входе проверяет разрешение экрана и меняет его , если надо и при выходе восстанавлмвает, если надо. Так вот когда я принудительно , для тестирования, выставила разрешение , которое надо изменить ну, скажем 640х480, погоняла прогу - все нормально, меняется и восстанавлмвается. Выхожу из проги, ставлю опять свое разрешение, работаю дальше, не с этой прогой, выключаю комп нормальным образом, а утром при включении - опять грузится разрешение 640х480! и кроме того 256 цветов, вместо 32 бит.
т.к. это уже было не один раз есть подозрение, что некорректно восстанавливается разрешение в проге (changedisplaysetting(режим,0)), может это связано с неполным определением той структуры, а почему вы так решили, что оно неполное?

--
Best regards,
olga

(Добавление)

Незная, что именно делает этот шаблон, трудно что-то предполагать.
Я не использую подобные методы - зачем? - пусть юзер сам определяет удобные для себя настройки рабочего стола стандартными средствами.
Но, судя по информации о данной функции из WinAPI, во время этих "игр" происходит запись настроек измененного режима в реестр. Это, кстати, может делать и другая программа:
- твоя прога изменила динамически режим экрана
(динамически - значит не пишет инфу о режиме в реестр)
- во время работы системы в этом измененном режиме кто-то производит обновление реестра, считая, например, текущий режим экрана дефолтным.
- после завершения работы твоей проги производится динамическая смена разрешения экрана на первоначальный.

НО! В реестре уже записана другая инфа! Которая, естественно, будет установлена в качестве дефолтной при следующем запуске системы!

Кстати, если уж "по-честному", то следовало-бы в конце проги вызвать вышеназванную функцию вообще без параметром, т.е.:
ChangeDisplaySetting(0,0)
В этом случае восстанавливается именно дефолтный режим экрана из реестра - по крайней мере, сразу будет видно, что что-то изменилось с дефолтными настройками.
А так - при выходе прога ДИНАМИЧЕСКИ как-бы "восстановила" дефолтный режим - а дальше - не наше дело!:))
может это связано с неполным определением той структуры, а почему вы так решили, что оно неполное?
Из описания этой структуры в том-же WinAPI!
Кроме того, что в вашем случае имеем неполную концовку структуры для минимального случая (> ОС W95), так еще нет обязательной концовки для W95-систем. Или Вы не используете программу под W9x?

Ну и, судя по Вашему предыдущему письму, не производится инициализация члена этой структуры, несущего информацию о текущем размере структуры. Для подобных структур в WinAPI это является чуть-ли не обязательным условием гарантированно-правильной обработки таких структур!
Или Вы плохо искали код этой инициализации?
Проще всего - проверить по сгенеренному коду ВСЕХ модулей программы - если такая инициализация производится, то она должна стоять, как минимум, перед первым использованием данной структуры. А по-хорошему, так вообще - перед каждым ее использованием.

=============================
С уважением, Олег А. Руденко

(Добавление)

Здравсвуйте Олег!
Я не использую подобные методы - зачем? - пусть юзер сам определяет удобные для себя настройки рабочего стола стандартными средствами.
Дело в том, что юзер не умеет этого делать:) и не хочет учиться:) а приходит на чужой комп с этой прогой, а там разрешение 800х600 и не помещается на экране бровз - надо листать - неудобно, вот и взяла чужой шаблон, он вроде простенький - проверяет текущий режим, если он не совпадает с требуемым - меняет его, а по окончании работы - восстанавливает оригинальное и вот после этого начинаются фокусы
- во время работы системы в этом измененном режиме кто-то производит обновление реестра, считая, например, текущий режим экрана дефолтным.
Кто? - я одна
- после завершения работы твоей проги производится динамическая смена разрешения экрана на первоначальный.
схема такова - загрузка системы-1024х768, меняем на 640х480 (в свойствах экрана), запускаю прогу устанавливает - 1024х768, конец проги - 640х480, что-то поделала другое, сменила через свойства экрана на 1024х768, поработала еще с чем-то, выключила комп, включила - 640х480 + 256 цветов
Из описания этой структуры в том-же WinAPI!
Я смотрела описание этой функции в справочнике (печатном) - и не нашла там никакого описания этой структуры, просто сказано, что третий параметр - структура, куда копируются данные, возвращаемые функцией
Кроме того, что в вашем случае имеем неполную концовку структуры для минимального случая (> ОС W95), так еще нет обязательной концовки для W95-систем. Или Вы не используете программу под W9x?
как раз под под нее, хотя тестировала на w2k
Или Вы плохо искали код этой инициализации?
Проще всего - проверить по сгенеренному коду ВСЕХ модулей программы
так и делала - нету ее:(

Спасибо огромное, Олег! Ситуация прояснилась по крайней мере:)
Написал: ClaList(2)
Гость

Сообщение Гость »

ИМХО, лучше не связываться со сменой разрешений экрана, а перепроектировать интерфейс, так что бы он влезал на минимальное разрешение, а при большем разрешении - при необходимости растягивал контролы, те. придерживался виндовых стандартов.
Опять же, ИМХО, ежели б я, скажем запустил какую прогу, а она начала б у меня ни с того ни с сего окошками хлопать и разрешения экрана менять, я был бы, хм..., ну скажем так маленько удивлён. :D

ЗЫ. Структура DEVMODE, которую ты используешь очень развесистая и ко всему прочему её размер и передаваемые параметры зависят от типа виндов. Вот ея описание из MSDN:

Код: Выделить всё

typedef struct _devicemode {
  BCHAR  dmDeviceName[CCHDEVICENAME];
  WORD   dmSpecVersion;
  WORD   dmDriverVersion;
  WORD   dmSize;
  WORD   dmDriverExtra;
  DWORD  dmFields;
  union {
    struct {
      short dmOrientation;
      short dmPaperSize;
      short dmPaperLength;
      short dmPaperWidth;
      short dmScale;
      short dmCopies;
      short dmDefaultSource;
      short dmPrintQuality;
    };
    POINTL dmPosition;
    DWORD  dmDisplayOrientation;
    DWORD  dmDisplayFixedOutput;
  };

  short  dmColor;
  short  dmDuplex;
  short  dmYResolution;
  short  dmTTOption;
  short  dmCollate;
  BYTE  dmFormName[CCHFORMNAME];
  WORD  dmLogPixels;
  DWORD  dmBitsPerPel;
  DWORD  dmPelsWidth;
  DWORD  dmPelsHeight;
  union {
    DWORD  dmDisplayFlags;
    DWORD  dmNup;
  }
  DWORD  dmDisplayFrequency;
#if(WINVER >= 0x0400)
  DWORD  dmICMMethod;
  DWORD  dmICMIntent;
  DWORD  dmMediaType;
  DWORD  dmDitherType;
  DWORD  dmReserved1;
  DWORD  dmReserved2;
#if (WINVER >= 0x0500) !! (_WIN32_WINNT >= 0x0400)
  DWORD  dmPanningWidth;
  DWORD  dmPanningHeight;
#endif
#endif /* WINVER >= 0x0400 */
} DEVMODE;
[/i]
С уважением,
Новиков Антон
anfront@mail.ru
ICQ #50995986
Написал: ClaList(2)
Гость

Сообщение Гость »

ЗЫ. Структура DEVMODE, которую ты используешь очень развесистая и ко всему прочему её размер и передаваемые параметры зависят от типа виндов. Вот ея описание из MSDN
да не я это!!! не виноватая я, он сам это делает :D
да и это был заказ - менять разрешение, ну каприз это... а вот может можно это из командной строки сделать перед запуском, типа в свойствах экрана поменять, а после выхода - опять на исходное. Это очень индивидуальная задача, не тиражируемая, а интерфейс не хочется резать, уж очень удобно было :)

--
Best regards,
olga
Кто? - я одна
Так ведь в "фоне" еще куча процессов работает!
Посмотри, хотя-бы, в трей - как минимум увидишь несколько иконок. А если посмотреть полный список активных процессов - просто жуть! :D
схема такова - загрузка системы-1024х768, меняем на 640х480 (в свойствах экрана), запускаю прогу устанавливает - 1024х768, конец проги - 640х480, что-то поделала другое, сменила через свойства экрана на 1024х768, поработала еще с чем-то, выключила комп, включила - 640х480 + 256 цветов
- есть-ли уверенность, что это все происходит из-за твоей проги? Возможно она здесь и ни причем?
- такое происходит на всех компах или только на данном?
если да - какая операционка?
Я смотрела описание этой функции в справочнике (печатном) - и не нашла там никакого описания этой структуры, просто сказано, что третий параметр - структура, куда копируются данные, возвращаемые функцией
Мы говорим об одной и той-же функции - ChangeDisplaySetting???
Если да, то где ты нашла у нее три параметра!?
У меня - только два параметра и первым идет адрес именно "проблемной" структуры DEVMODE!

=============================
С уважением, Олег А. Руденко
А если посмотреть полный список активных процессов - просто жуть! :D
тогда получается нет смысла восстанавливать дефолтный режим, если считать что какой-нить процесс за время моей работы может обновить реестр, считая текущий видеорежим дефолтным...
а в трее висят антивирус, лингва, пунта, телефон
- есть-ли уверенность, что это все происходит из-за твоей проги? Возможно она здесь и ни причем?
- такое происходит на всех компах или только на данном?
если да - какая операционка?
похоже из-за нее, у меня это проявляется на w2k , на winXP, и сама не видела, но со слов - на w98
У меня - только два параметра и первым идет адрес именно "проблемной" структуры DEVMODE!
нет, Олег, первоначально речь шла о enumDisplaySettings - у нее три параметра, она портила мою переменную, потом уже о ChangeDisplaySetting,с двумя конечно, она некорректно восстанавливала режим.

--
Best regards,
olga

(Добавление)
Кстати, если уж "по-честному", то следовало-бы в конце проги вызвать вышеназванную функцию вообще без параметром, т.е.: ChangeDisplaySetting(0,0)
не хочет она принимать функцию в таком виде - д.б.идентификатор. NULL тоже не признает, я имею в виду для первого параметра

с уважением Ольга

Надо переопределить прототип этой функции.
Сейчас у тебя, очевидно, в прототипе прописано что-то типа
ChangeDisplaySettings(*DEVMODE,DWORD)...

Надо поменять на: ChangeDisplaySettings(LONG,LONG)
Правда, надо будет еще и изменить все вызовы этой
функции - ChangeDisplaySettings(Address(GLO:DM),...).

=============================
С уважением, Олег А. Руденко

сделала так - теперь не восстанавливает при выходе - остается то, что было в проге. Такой же эффект быо, когда я не переопределяла прототип, а clear(glo:dm)сделала перед вызовом этой функции

--
Best regards,
olga
Написал: ClaList(2)
Гость

Сообщение Гость »

Ну, если используешь вариант вызова этой функции с параметрами, то очищать структуру DevMode не следует - именно в ней и хранится информация о режиме экрана, который необходимо установить. Эту инфу туда можешь записать или сама или, как очевидно в твоем случае, это делает функция EnumDisplaySettings, которая должна вызываться в начале твоей проги.
Что-же касается того, что без параметров не происходит восстановление исходного режима экрана, то дело, очевидно в следующем:
- я предполагал, что у тебя ChangeDisplaySettings устанавливает новый режим динамически, без записи изменений в реестр.
Но, очевидно, она это делает с изменением и реестра.
Второй параметр функции как раз и управляет этим поведением - если он =0, то производится динамическое изменение режима БЕЗ модификации реестра. В противном случае производится еще и запись новых данных в реестр. Возможно именно это и является причиной всех последующих "приключений".

Исходя из этого, могу посоветовать следующее:
- исправь обьявление структуры DevMode на правильное - особенно это касается последнего параметра в твоем обьявлении этой структуры из первого письма - он должен быть DWORD.
Именно пять последних параметра и изменяет функция Enum...
На всякий случай ПЕРЕД вызовом Enum... сделай:

Clear(GLO:DM)
GLO:DM.dmSize = SIZE(GLO:DM)

Если, конечно, этого не делает сам шаблон.
- НЕ изменяй и не очищай структуру DevMode после отработки функции EnumDisplaySettings.
- если вызовы функции ChangeDisplaySettings (кроме последнего) используют второй параметр <>0, то измени его на 0.
Я исхожу из того, что в задачи твоей проги НЕ входит полное изменение режима экрана "на всегда"? Т.е., необходимо именно временное изменение режима? Кстати, у этого подхода есть еще один плюс - в случае краха системы во время работы программы, после перезагрузки будет восстановлен первоначальный режим работы экрана!
- последний вызов этой функции сделай без параметров (0,0).

Удачи!
=============================
С уважением, Олег А. Руденко

Здравствуйте, olga.

Несколько поздно может быть, но clarionlife.net/кларионисты/Стефаненко Евгений/Ресурсы человека на сайте/Изменение разрешения экрана - changeres.rar.

С уважением,
Still mailto:zero@clarionlife.net

Написал: ClaList(2)
Гость

Сообщение Гость »

Несколько поздно может быть, но clarionlife.net/кларионисты/Стефаненко Евгений/Ресурсы человека на сайте/Изменение разрешения экрана - changeres.rar.
лучше поздно, чем никогда :) спасибо, посмотрю
Ну, если используешь вариант вызова этой функции с параметрами, то очищать структуру DevMode не следует - именно в ней и хранится информация о режиме экрана, который необходимо установить.
я не могла просто написать change...(0,0) или (NULL,0), поэтому только перед последним вызовом этой функции я и очистила эту структуру
Возможно именно это и является причиной всех последующих "приключений".
шаблон вызывает эту функцию со вторым параметром= и 1h и 2h и 0
что они означают?
после исправления второго параметра на 0 во ВСЕХ вызовах началась карусель с переключениями - мельтешило несколько секунд (не меньше 10),вроде как перебирало все доступные режимы, потом вылезло совершенно дикое разрешение, а после выхода - снова пошел перебор,и восстановилось опять не то.
разрешение
Если я вас не еще не утомила :), то вот что я выяснила, шаблон (не мой!)
- определяет текущие установки экрана (разрешение и глубину цвета),
- перебирает все доступные режимы с помощью enumDisplaySettings ( если возвращаемое значение этой функции <0 , то заполнение очереди заканчивается) и changeDisplaySettings(glo:dm, 2h) и заполняет глобальную очередь доступных режимов,

Код: Выделить всё

SOLDisplayQ              QUEUE,PRE(GDQ)
Desc                       STRING(30)
Height                     LONG
Width                      LONG
BitsPerPel                 BYTE
DMode                      LONG
OK                         BYTE
                         END
- потом в зависимости от логического условия - надо или нет - переключает режим,а именно: сохранив перед этим текущие установки в глобальных переменных, ищет нужный режим в глобальной очереди режимов

и

Код: Выделить всё

X# = EnumDisplaySettings(0,GDQ:DMode,GLO:DM)

 r# = ChangeDisplaySettings(GLO:DM,2h)
   case r#
   of 0
     r# = ChangeDisplaySettings(GLO:DM,1h)
   of 1
     !That would mean restarting the PC
   else
     !That would screw things good and proper
   end
- при выходе
RestoreOriginal     Routine
   do GetOrigQueueRecord ----восстанавливает  оригинальный режим
   X# = EnumDisplaySettings(0,GDQ:DMode,GLO:DM)
   r# = ChangeDisplaySettings(GLO:DM,2h)
   if r# = 0 then
     r# = ChangeDisplaySettings(GLO:DM,1h)
   end
не понятно, что означают второй параметр= 1h и 2h, но пока я не меняла второго параметра на 0, визуального мелькания не было
- исправь обьявление структуры DevMode на правильное - особенно это касается последнего параметра в твоем обьявлении этой структуры из первого письма - он должен быть DWORD.
прошу прощения за подобный вопрос - но в кларе ведь нет DWORD, вроде бы - с winapi я впервые сталкиваюсь
Если, конечно, этого не делает сам шаблон.
Шаблон этого не делает
Я исхожу из того, что в задачи твоей проги НЕ входит полное изменение режима экрана "на всегда"? Т.е., необходимо именно временное изменение режима?
совершенно верно
последний вызов этой функции сделай без параметров (0,0).
тогда параметры в прототипе должны быть описаны ведь как long ?
а в enum... тоже д.б. long для описания этой структуры?

Прошу прощения за столь длинное письмо
с уважением Ольга

(Добавление)

Здравствуйте, olga!

четверг, 17 июня 2004 г., Вы писали:
r# = ChangeDisplaySettings(GLO:DM,2h)
2h - тест возможности установки заданного режима
case r#
of 0
0 - можно изменить сразу
r# = ChangeDisplaySettings(GLO:DM,1h)
1h - изменение режима И модификация реестра
of 1
1 - можно изменить ТОЛЬКО после перезагрузки компа
RestoreOriginal Routine
do GetOrigQueueRecord ----восстанавливает оригинальный режим
X# = EnumDisplaySettings(0,GDQ:DMode,GLO:DM)
r# = ChangeDisplaySettings(GLO:DM,2h)
2h - тест возможности установки заданного режима
if r# = 0 then
r# = ChangeDisplaySettings(GLO:DM,1h)
1h - изменение режима И модификация реестра
не понятно, что означают второй параметр= 1h и 2h, но
см. выше
пока я не меняла второго параметра на 0, визуального мелькания не было
НЕ НАДО менять второй параметр функции Change... если он равен 2 - пусть проверяет возможность установки заданного режима. Поменяй только 1 на 0.
Вообщем идея такая - проверку оставляем, а вместо кардинального изменения режима с модификацией реестра (второй параметр=1) используем ДИНАМИЧЕСКОЕ изменение режима (второй параметр=0).
прошу прощения за подобный вопрос - но в кларе ведь нет DWORD, вроде бы - с winapi я впервые сталкиваюсь
В файле WinAPI.clw тип DWORD обьявлен как ULONG.
Т.е., можно конечно писать в прототипах просто ULONG.
Вообщем - кому как нравится.
тогда параметры в прототипе должны быть описаны ведь как long ?
а в enum... тоже д.б. long для описания этой структуры?
Прототип вызова функции Enum... можно и не изменять.

=============================
С уважением, Олег А. Руденко

Олег , спасибо огромное за помощь и терпение - добила я его все-таки - теперь нормально все работает
всего-то надо было разобраться со вторым параметром :)

--
Best regards,
olga
Написал: ClaList(2)
Ответить