Если вы читаете очень старый код, вы часто можете видеть преобразования типов, которые кажутся избыточными.
SendMessage(hwndListBox, LB_ADDSTRING, 0, (LPARAM)(LPSTR)"string");
Почему "string" преобразуется в LPSTR? Она же уже LPSTR!
Это наследство из 16-ти битных Windows. Вспомните, что в мире 16-ти битных Windows указатели по-умолчанию были ближними. Соответственно, "string" была ближним указателем на строку. Если бы код был бы написан как
SendMessage(hwndListBox, LB_ADDSTRING, 0, (LPARAM)"string");
То при этом взялся бы ближний указатель и он был бы преобразован к long. Поскольку ближний указатель является 16-ти битным значением, указатель просто был был расширен нулями до размера long в 32 бита.
Однако, все указатели в оконных сообщениях должны быть дальними указателями, потому что оконные процедуры для окна могут быть реализованы в модуле, отличном от модуля отправителя сообщения. Вспомните, что ближние указатели трактуются относительно селектора по-умолчанию, а селектор по-умолчанию для каждого модуля свой. Отправка ближнего указателя в другой модуль приведёт к тому, что указатель будет трактоваться относительно селектора по-умолчанию принимающей стороны, который отличен от селектора по-умолчанию отправителя.
Промежуточное преобразование в LPSTR конвертирует ближний указатель в дальний указатель. LP - это префикс венгерской нотации для дальних указателей (также известных как "длинные указатели" - "long pointers"). Преобразование ближнего указателя в дальний указатель вставит ранее только подразумевавшийся селектор по-умолчанию, так что следующее преобразование к LPARAM возьмёт полный 16:16 дальний указатель.
Ну, неужели вы не рады, что вам больше не нужно беспокоиться о таких вещах?
Прим. пер.: я оставил здесь всё на C, т.к. я уже не помню, как там было в 16-ти разрядном Паскале, и в какой степени всё сказанное к нему применимо.
как преобразовать string в lparam?
ОтветитьУдалить"...я оставил здесь всё на C..." НАКОНЕЦ-ТО!
ОтветитьУдалить