Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2002.01.21;
Скачать: [xml.tar.bz2];

Вниз

Помогите найти ошибку   Найти похожие ветки 

 
Moscower   (2001-11-16 16:13) [0]

Видимо, конечно, в силу моей криворукости при программировании WinApi на Delphi возникают ошибки... :-( Подскажите пожалуйста, что я делаю не так?



program MVROrganizer;

uses
Windows, Dialogs, SysUtils, ole2auto,
Forms,
Tray in "Tray.pas" {Form1};

var fmhandle : HWND;
tekhandl : PChar;
temp : LongWord;
ptk, p1 : pointer;
outp : String;
lpMsgBuf : String;
{$R *.res}

begin

Application.Initialize;
tekhandl := PChar(IntToStr(Application.Handle)); // Находим хэндл главной формы приложения и запоминаем его в переменную tekhandl
fmhandle := CreateFileMapping(HWND($FFFFFFFF), nil, PAGE_READONLY, 0, sizeof(HWND), "Moscower"); // создаем карточный файл
if GetLastError<>ERROR_ALREADY_EXISTS then
begin
Application.CreateForm(TForm1, Form1);
if not WriteFile(fmHandle, ptk, sizeof(tekhandl), temp, nil) // пытаемся записать в него хэндл главной формы приложения
then
begin
// если ошибка
SetLength(lpMsgBuf, 256);
SetLength( lpMsgBuf, FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER or FORMAT_MESSAGE_FROM_SYSTEM,
nil,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
@lpMsgBuf[1],
255,
nil
));// то формируем сообщение о ней


MessageBox( Application.Handle, Pchar(lpMsgBuf), "GetLastError", MB_OK or MB_ICONINFORMATION ); // И выводим на экран
CloseHandle(fmhandle);

Application.Run;

end ;



end


end.



Код для обработки ошибки взял из SDK, видимо неудачно перевел его с C на Delphi...

Ошибки:

1. В карточный файл ничего не записывается и он идет на ошибку
2. Не могу получить сообщение об ошибке, вместо него показывается непереводимый набор символов.

Поправьте меня пожалуйста, как это нужно делать?


 
paul_shmakov   (2001-11-16 16:41) [1]

это вообще какой-то некоректный способ работы с файлами, проецируемыми в память. какая задача?
1. нужно создать объект-ядра "файл, проецируемый в память" (memory mapped file). создаеться он функцией CreateFileMapping. в первом ее параметре нужно передать дескриптор открытого файла или $FFFFFFFF, что говорит системе, что память под этот файл следует взять из страничного файла (или свопа по нашему). только не нужно это значение к HWND приводить, как в примере выше. если мы в этот файл что-то писать собрались, то нужно передать PAGE_READWRITE, а не PAGE_READONLY. размер файла указан верно. следует заметить, что если мы в первом параметре передали $FFFFFFFF, то не можем передать 0 вместо размера. если в первом параметре дескриптор на открытый файл, то можно передать 0 - файл целиком спроецируется.

2. спроецировать файл на адресное пространство процесса функцией MapViewOfFile. по тому значению, которое она вернет можно записать то, что нам нужно.

var
P: PChar;
begin
...
P := MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
StrCopy(P, "что-то, что нужно засунуть в файл");


3. вызвать UnmapViewOfFile и CloseHandle.


 
Moscower   (2001-11-16 17:42) [2]

СПАСИБО!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
РАБОТАЕТ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!


Прошу прощения за вот такой вопрос, просто увидел, у Ю. Зотова в примере cunnings на королевстве, как сделать так, чтобы программу можно было запустить только один раз. Вот я и решил доработать этот код с тем, чтобы в этот mapping file можно было записать handle процесса, а потом из программы, запущенной 2-ой раз прочитать его, и сделать активной форму с этим хэндлом. Но я абсолютно не знал, что это за mapping файл такой. Огромное спасибо, что разъяснили, как с ним работать!!!!!!!!!!!!!!!!!!!



 
paul_shmakov   (2001-11-16 23:07) [3]

сделать форму активной лучше не так. создаем, значит, файл, проецируемый в память, и тут видим, что он уже создан.
тогда делаем следующее: находим главное окно нашей программы с помощью FindWindow, посылаем в него какое-либо сообщение, нами определенное (например, WM_APP + 100).
в главное форме должен быть перехватчик-обработчик этого сообщения, который должен вызывать Application.BringToFront.
это самый нормальный способ.


 
Moscower   (2001-11-17 00:07) [4]

А чем это лучше, чем мой способ?


 
paul_shmakov   (2001-11-17 02:10) [5]

это сложнее и не особо нужно. хотя можно и вашим способом.
дело в другом. берем хэндл главного окна предыдущей копии (с помошью FindWindow или из файла считать). далее не нужно вызывать всякие ShowWindow(hwnd, SW_RESTORE), BringWindowToTop(hwnd), SetForegroundWindow и т.п.
а нужно послать в эту форму какое-то свое сообщение, которое она обрабатывая вызовет Application.BringToFront.
получается самый нормальный вариант (особенно, если куча модальных дочерних окошек открыта).


 
Raptor   (2001-11-17 10:29) [6]

Привет!

2paul_shmakov ©
Тут лучше использовать не файлы проэцируемые на память, а мютексы или атомы. Они есть объекты ядра и с 100% увереностью можна сказать, что два атома не не могут быть созданы одновременно. А с файлами есть возможность того, что они будут создаваться одновременно и Ваш метод не сработает.

Raptor.


 
paul_shmakov   (2001-11-18 15:54) [7]

2 Raptor:
проецируемый в память файл (memory mapped file) является 100%-ным объектом ядра наряду с мютексами, событиями, семафорами и т.д.


 
Raptor   (2001-11-18 21:42) [8]

Привет!

2paul_shmakov
Да, Вы правы. Извиняюсь.

2Moscower
Если Вас интересует проблема запуска только одной копии приложения советую почитать эту статью:
http://www.pgh.net/~newcomer/nomultiples.htm
или ее перевод:
http://www.rsdn.ru/article/?baseserv/avins.xml

Raptor.


 
Moscower   (2001-11-19 11:02) [9]

>Raptor
Спасибо, почитаю



Страницы: 1 вся ветка

Форум: "WinAPI";
Текущий архив: 2002.01.21;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.47 MB
Время: 0.004 c
1-66280
Lazyk
2002-01-04 14:57
2002.01.21
Printer accounting


1-66261
Smile
2002-01-01 20:51
2002.01.21
Изменение вида кнопки


1-66243
Mis
2002-01-02 13:41
2002.01.21
Как сделать паузу.


3-66210
IBPlus
2001-12-18 12:14
2002.01.21
Кодировки


6-66331
Роллер
2001-10-25 10:51
2002.01.21
Windows SocketError: что за ошибки?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский